/*
 * @(#)MaintCalendarRecordAction.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.calendar.web;

import java.io.IOException;
import java.net.URLEncoder;
import java.sql.Connection;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.fortuna.ical4j.data.CalendarOutputter;
import net.fortuna.ical4j.model.Calendar;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.util.LabelValueBean;

import com.dcivision.alert.bean.MtmUpdateAlertRecipient;
import com.dcivision.alert.bean.UpdateAlert;
import com.dcivision.alert.bean.UpdateAlertLogAction;
import com.dcivision.alert.bean.UpdateAlertSystemLog;
import com.dcivision.alert.bean.UpdateAlertType;
import com.dcivision.alert.core.AlertManager;
import com.dcivision.alert.dao.MtmUpdateAlertRecipientDAObject;
import com.dcivision.alert.dao.UpdateAlertDAObject;
import com.dcivision.alert.dao.UpdateAlertSystemLogDAObject;
import com.dcivision.alert.dao.UpdateAlertTypeDAObject;
import com.dcivision.calendar.bean.CalendarRecord;
import com.dcivision.calendar.bean.CalendarRecur;
import com.dcivision.calendar.core.CalendarRetrievalManager;
import com.dcivision.calendar.dao.CalendarRecordDAObject;
import com.dcivision.calendar.dao.CalendarRecurDAObject;
import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.ErrorConstant;
import com.dcivision.framework.GlobalConstant;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemFunctionConstant;
import com.dcivision.framework.SystemParameterConstant;
import com.dcivision.framework.SystemParameterFactory;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.Utility;
import com.dcivision.framework.bean.AbstractBaseObject;
import com.dcivision.framework.web.AbstractActionForm;
import com.dcivision.user.bean.UserGroup;
import com.dcivision.user.bean.UserGroupPermission;
import com.dcivision.user.bean.UserRecord;
import com.dcivision.user.bean.UserRecordPermission;
import com.dcivision.user.bean.UserRole;
import com.dcivision.user.bean.UserRolePermission;
import com.dcivision.user.dao.UserGroupDAObject;
import com.dcivision.user.dao.UserGroupPermissionDAObject;
import com.dcivision.user.dao.UserRecordDAObject;
import com.dcivision.user.dao.UserRecordPermissionDAObject;
import com.dcivision.user.dao.UserRoleDAObject;
import com.dcivision.user.dao.UserRolePermissionDAObject;

/**
 * <p>
 * Class Name: MaintCalendarRecordAction.java
 * </p>
 * <p>
 * Description: The maint action class for EditCalendar.jsp
 * </p>
 * 
 * @author Robert Jin
 * @company DCIVision Limited
 * @creation date 18/12/2003
 * @version $Revision: 1.97.2.1 $
 */
public class MaintCalendarRecordAction extends
    com.dcivision.alert.web.MaintUpdateAlertAction {
  /** Navigation mode for Reply. */
  public final static String NAV_MODE_REPLY = "RE";
  
  /** Navigation mode for Share. */
  public final static String NAV_MODE_SHARE = "SH";

  /** Permission type representing READONLY of the permission. */
  public static final String PERMISSION_READONLY = "R";

  /** Permission type representing TITLE READONLY of the permission. */
  public static final String PERMISSION_READ_TITLE_ONLY = "T";

  /** Permission type representing READWRITE of the permission. */
  public static final String PERMISSION_READWRITE = "W";

  public MaintCalendarRecordAction() {
    super();
  }

  /**
   * getFunctionCode
   * 
   * @return The corresponding system function code of action.
   */
  public String getFunctionCode() {
    return (SystemFunctionConstant.SCHEDULE_CALENDAR);
  }

  /**
   * getMajorDAOClassName
   * 
   * @return The class name of the major DAObject will be used in this action.
   */
  public String getMajorDAOClassName() {
    return ("com.dcivision.calendar.dao.CalendarRecordDAObject");
  }

  public ActionForward execute(ActionMapping mapping, ActionForm form,
      HttpServletRequest request, HttpServletResponse response)
      throws ServletException {
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection connection = this.getConnection(request);
    ActionForward forward = this.retrieveFunctionCode(request, response,
        mapping);

    if (forward != null) {
      return forward;
    }
    MaintCalendarRecordForm maintForm = (MaintCalendarRecordForm) form;
    String opMode = request.getParameter("opMode");
    String navMode = request.getParameter("navMode");
    if("EXP".equals(navMode)){//exp to icalendar
      expCalendar(request, response, maintForm);
      return null;
    }

    //set the attributes of user, group and role list
    setAllUserGroupRoleAttributes(form, request);

    //if get calendar from personal home page by reminded log
    if (!Utility.isEmpty(request.getParameter("isReminded"))) {
      if (!Utility.isEmpty(request.getParameter("systemLogID"))) {
        Integer systemLogID = new Integer(Integer.parseInt(request
            .getParameter("systemLogID")));
        setSystemLogToRead(systemLogID, request);
      }
    }
    
    if (GlobalConstant.NAV_MODE_REFRESH.equals(opMode)) {
      refreshFormData(mapping, form, request, response);
      return mapping.findForward(GlobalConstant.NAV_MODE_REFRESH);
    } else if (NAV_MODE_REPLY.equals((opMode))) {
      try {
        replyOnInvite(mapping, form, request, response);
      } catch (ApplicationException appEx) {
      	/*
      	 *	Update Code Start
      	 *	Author				Jim.Zhou
      	 *	Date					2006/06/05
      	 *	Bug						#3950
      	 */
      	this.rollback(request);
        this.handleApplicationException(request, appEx);

        if (this.isError(request)) {
          maintForm.setNavMode(GlobalConstant.NAV_MODE_VIEW);
          
          request.setAttribute("opReply","True");
          request.setAttribute("ID",request.getParameter("ID"));
          request.setAttribute("systemLogID",request.getParameter("systemLogID"));
          request.setAttribute("isHome","true");
          
          return mapping.findForward(GlobalConstant.NAV_MODE_VIEW);
        }
        /*
         *	Update Code End
         */
      }
      try{
        response.sendRedirect("../Home.do");
        return null;
      }catch(IOException e){
        return mapping.findForward("H");
      }  
      //form.reset(mapping, request);
      //return mapping.findForward(GlobalConstant.NAV_MODE_LIST);    
      /*
       *	Update Code End
       */ 
    } else if (NAV_MODE_SHARE.equals((opMode))) {
      try {
        //      delete permission list be object type and ID
        CalendarRecord calendarRecord = new CalendarRecord();
        calendarRecord.setID(new Integer(maintForm.getID()));
        deletePermissionListByObjectTypeObjectID(sessionContainer, connection,
            calendarRecord);
    	createCalendarRecordSharing(sessionContainer, connection, maintForm);
        this.commit(request);
      } catch (ApplicationException appEx) {
        this.handleApplicationException(request, appEx);

        if (this.isError(request)) {
          maintForm.setNavMode(GlobalConstant.NAV_MODE_VIEW);
          return mapping.findForward(GlobalConstant.NAV_MODE_VIEW);
        }
      }
      maintForm.setNavMode(GlobalConstant.NAV_MODE_VIEW);
      return mapping.findForward(GlobalConstant.NAV_MODE_VIEW);     
    } else if ("LS".equals(navMode)) {
      return mapping.findForward("LS");
    } else {
      if("Y".equals(request.getParameter("QA"))){
      	/*
      	 * Update Code Start
      	 * Author					Jim.Zhou
      	 * Date						2006/05/25
      	 * Bug						#5416
      	 */
        return super.execute(mapping, form, request, response);
        /*
        try{
          response.sendRedirect("ListCalendar.do?navMode="+request.getParameter("newNavMode"));
          return null;
        }catch(IOException e){
          return mapping.findForward(GlobalConstant.NAV_MODE_VIEW);
        }
         */
        /*
         * Update Code End
         */
      } else {
        return super.execute(mapping, form, request, response);
        /*
      	ActionForward actionForward = super.execute(mapping, form, request, response);      	
        if (this.isError(request)){
          this.addError(request,"errors.calendar.has_deleted");
          return mapping.findForward("ER");
        } else {
          if ("True".equals(request.getParameter("opReply")) && !checkLoginId(mapping, form, request, response)){
            //add error
            this.addError(request,"errors.calendar.no_permission_to_invit_meeting");
            return mapping.findForward("ER");
          }
        }
        return actionForward;
        */
      }      
    }

  }

  /**
   * selectRecord
   * 
   * select record information
   * 
   * @param mapping
   * @param form
   * @param request
   * @param response
   * @throws ApplicationException
   */
  public void selectRecord(ActionMapping mapping, AbstractActionForm form,
      HttpServletRequest request, HttpServletResponse response)
      throws ApplicationException {
    Connection connection = this.getConnection(request);
    List meetingList = new ArrayList();
    String[] sharingUserIDs = null;
    String[] sharingGroupIDs = null;
    String[] sharingRoleIDs = null;
    String[] meetingUserIDs = null;

    try {
      MaintCalendarRecordForm tmpForm = (MaintCalendarRecordForm) form;
      Integer ss = new Integer(1);
      SessionContainer sessionContainer = this.getSessionContainer(request);
      CalendarRecordDAObject calendarRecordDAO = new CalendarRecordDAObject(
          sessionContainer, connection);
      CalendarRecord calendarRecord = (CalendarRecord) calendarRecordDAO
          .getObjectByID(TextUtility.parseIntegerObj(tmpForm.getID()));

      //tmpForm.setDatetime(calendarRecord.getDatetime());
      //tmpForm.setEndtime(calendarRecord.getEndtime());
      tmpForm = setUserSharingList(sessionContainer, connection,
          calendarRecord, tmpForm);
      tmpForm = setGroupSharingList(sessionContainer, connection,
          calendarRecord, tmpForm);
      tmpForm = setRoleSharingList(sessionContainer, connection,
          calendarRecord, tmpForm);

      //invite meeting
      calendarRecord = selectInviteMeeting(request, sessionContainer,
          connection, calendarRecord);

      if (calendarRecord.getUpdateAlertID() != null) {
        //UpdateAlertTypeDAObject updateAlertTypeDAO=new
        // UpdateAlertTypeDAObject(sessionContainer,connection);
        //updateAlertTypeDAO.getByUpdateAlertIDByOwnerID(calendarRecord.getUpdateAlertID(),)
        calendarRecord = setReplyAttributes(request, sessionContainer,
            connection, calendarRecord);
      }

      //for recurring record
      if ("Y".equals(calendarRecord.getIsRecurrence())) {
        calendarRecord = selectRecurringRecord(sessionContainer, connection,
            calendarRecord);
      }

      tmpForm.setFormData(calendarRecord);
      tmpForm.setDatetime(calendarRecord.getDatetime());
      tmpForm.setEndtime(calendarRecord.getEndtime());
      List subList = null;
      if (!Utility.isEmpty(calendarRecord.getParentID())) {
        subList = calendarRecordDAO.getListByParentID(calendarRecord
            .getParentID().toString());
        if (!GlobalConstant.NAV_MODE_VIEW.equals(tmpForm.getNavMode())) {
          tmpForm.setDatetime(((CalendarRecord) subList.get(0)).getDatetime());
          tmpForm.setEndtime(((CalendarRecord) subList.get(subList.size() - 1))
              .getEndtime());
          int titleLen = calendarRecord.getTitle().lastIndexOf("-");
          if (titleLen > 0) {
            tmpForm.setTitle(calendarRecord.getTitle().substring(0, titleLen));
          }
          request.setAttribute("subList", subList);
          tmpForm.setSubMeetingNum(subList.size());
          tmpForm.setPriority(null);
        }
      }

      //set invite userRecords,userGroups,userRoles
      //get update alert recipient
      List recipientAry = new ArrayList();
      MtmUpdateAlertRecipientDAObject updateRecipientDAO = new MtmUpdateAlertRecipientDAObject(
          sessionContainer, connection);

      // Get all recipients.
      String recipientType = null;
      String[] tmprecipientAry = new String[0];

      if (!Utility.isEmpty(tmpForm.getUpdateAlertID())) {
        recipientAry = updateRecipientDAO.getByUpdateAlertID(new Integer(
            tmpForm.getUpdateAlertID()));
      }

      tmprecipientAry = new String[recipientAry.size()];

      String[] userRecords = new String[recipientAry.size()];
      String[] userGroups = new String[recipientAry.size()];
      String[] userRoles = new String[recipientAry.size()];

      for (int i = 0; i < recipientAry.size(); i++) {
        MtmUpdateAlertRecipient tmprecipient = (MtmUpdateAlertRecipient) recipientAry
            .get(i);

        if (tmprecipient.getRecipientType().equals(UpdateAlert.USER_RECIPIENT)) {
          userRecords[i] = tmprecipient.getRecipientID().toString();
        } else if (tmprecipient.getRecipientType().equals(
            UpdateAlert.GROUP_RECIPIENT)) {
          userGroups[i] = tmprecipient.getRecipientID().toString();
        } else if (tmprecipient.getRecipientType().equals(
            UpdateAlert.ROLE_RECIPIENT)) {
          userRoles[i] = tmprecipient.getRecipientID().toString();
        }
      }

      if (recipientAry.size() > 0) {
        tmpForm.setUserList(userRecords);
        tmpForm.setGroupList(userGroups);
        tmpForm.setRoleList(userRoles);
      }
    } catch (Exception e) {
      log.error("Retrieve calendar record information.", e);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR, e);
    }

    connection = null;
  }

  public void insertRecord(ActionMapping mapping, AbstractActionForm form,
      HttpServletRequest request, HttpServletResponse response)
      throws ApplicationException {
    Connection connection = this.getConnection(request);
    SessionContainer sessionContainer = this.getSessionContainer(request);
    AlertManager alertManager = new AlertManager(sessionContainer, connection);
    UpdateAlert newUpdateAlert = null;
    CalendarRecord calendarRecord = null;
    CalendarRecordDAObject calendarRecordDAObject = new CalendarRecordDAObject(
        sessionContainer, connection);
    int minuteInterval = SystemParameterFactory.getSystemParameterInteger(SystemParameterConstant.CALENDAR_DEFAULT_TIMEPICKER_INTERVAL).intValue();
    try {
      MaintCalendarRecordForm tmpForm = (MaintCalendarRecordForm) form;
      //if have submeeting element ,
      //   if
      // (CalendarRecord.EVENT_TYPE_CALENDAR_MEETING.equals(tmpForm.getEventType())
      // && tmpForm.getSubMeetingNum() > 1 ){

      if (tmpForm.getSubMeetingNum() > 1) {
        updateSubCalendar(mapping, form, request, response);
      } else {
        tmpForm.setReminderType(((tmpForm.getEmailReminder() == null) ? ""
            : tmpForm.getEmailReminder())
            + ","
            + ((tmpForm.getSystemReminder() == null) ? "" : tmpForm
                .getSystemReminder()));

        if (!(CalendarRecord.NAV_MODE_LIST_TODO.equals(tmpForm.getEventType()))
            && (tmpForm.getEndtime() == null)) {
          tmpForm = this.setFormDate(tmpForm);
        }

        String[] userRecords = null;
        String[] userRoles = null;
        String[] userGroups = null;

        userRecords = request.getParameterValues("userRecords");
        userRoles = request.getParameterValues("userRoles");
        userGroups = request.getParameterValues("userGroups");

        //reset the starttime and endtime if it is a wholeday event
        if ("Y".equals(tmpForm.getIsWholeDay())) {
          tmpForm.setStartHour("00");
          tmpForm.setStartMinute("00");
          tmpForm.setEndHour("23");
          tmpForm.setEndMinute(String.valueOf(60-minuteInterval));
        }
        
        Timestamp strCurrentDate = Utility.getCurrentTimestamp();
        if (tmpForm.getRecurEndDate() != null) {
          if (tmpForm.formateStringToTimestamp(tmpForm.getRecurStartDate())
              .after(
                  tmpForm.formateStringToTimestamp(tmpForm.getRecurEndDate()))) {
            throw new ApplicationException(
                ErrorConstant.CALENDAR_RECURRING_RANGE_ERROR);
          }
          tmpForm.setRecurEndDate(tmpForm.getRecurEndDate().replaceAll("00:00:00","23:55:00"));
        }

        //check overlap with others
        /*
         * if (!"true".equals(SystemParameterFactory.getSystemParameter(
         * SystemParameterConstant.CALENDAR_ALLOW_OVERLAP))) { if
         * (!CalendarRecord.EVENT_TYPE_CALENDAR_TODO.equals(
         * tmpForm.getEventType()) && (tmpForm.getEventType() != null)) { if
         * (overlapWithOthers(request, tmpForm, null)) { throw new
         * ApplicationException(ErrorConstant.CALENDAR_OVERLAP_ERROR); } } }
         */


        ArrayList re = new ArrayList();
        re.add(tmpForm.getFormData());
        if (!Utility.isEmpty(tmpForm.getIsRecurrence()) && tmpForm.getIsRecurrence().equals("Y")){
        	try{
            //ArrayList re = (ArrayList)selfTimeConflict(sessionContainer,connection,tmpForm);
            re.addAll(selfTimeConflict(sessionContainer,connection,tmpForm));
        	} catch (ApplicationException e){
            log.error("CalendarRecord self conflict.", e);
            throw e;
        	} catch (Exception e){
        		log.error(e);
        		throw e;
        	}
        }
        
        
        String overlap = "yes";
        if (!Utility.isEmpty(request.getParameter("Overlap"))) {
          overlap = request.getParameter("Overlap");
        }
        
        if (!Utility.isEmpty(tmpForm.getIsRecurrence()) && tmpForm.getIsRecurrence().equals("Y") && Utility.isEmpty(tmpForm.getRecurEndDate())){
        	overlap = "no";
        }

        //check overlap with others
        if ("yes".equals(overlap)
            && !"true"
                .equals(SystemParameterFactory
                    .getSystemParameter(SystemParameterConstant.CALENDAR_ALLOW_OVERLAP))) {
          if (!CalendarRecord.EVENT_TYPE_CALENDAR_TODO.equals(tmpForm
              .getEventType())
              && (tmpForm.getEventType() != null)) {
          	//Update By Jim.Zhou		2006/06/30			Bug	#3950
            //ArrayList overlapList = getOverlapList(request, form,
            //    new Integer(0));
          	ArrayList overlapList = this.getAllOverlapList(request,form,new Integer(0),re);
          	//Update End
            //if (overlapWithOthers(request, form, null)) {
            if (overlapList.size() > 0) {
              request.setAttribute("overlapList", overlapList);

              tmpForm.setUserList(userRecords);
              tmpForm.setRoleList(userRoles);
              tmpForm.setGroupList(userGroups);

              throw new ApplicationException(
                  ErrorConstant.CALENDAR_OVERLAP_ERROR);
            }
          }
        }

        calendarRecord = (CalendarRecord) calendarRecordDAObject
            .insertObject(tmpForm.getFormData());
        
        tmpForm.setID(calendarRecord.getID().toString());
        //SHARING BY USERS, ROLES, AND GROUPS
        if (!(CalendarRecord.SHARE_TYPE_PRIVATE.equals((calendarRecord
            .getShareType())))) {
          tmpForm = this.createCalendarRecordSharing(sessionContainer,
              connection, tmpForm);
        }

        //Creat new alert information
        if (CalendarRecord.EVENT_TYPE_CALENDAR_MEETING.equals(calendarRecord
            .getEventType())) {
          String recipientType = (request.getParameter("recipientType") == null) ? ""
              : request.getParameter("recipientType");
          String[] notifyWayString = (request.getParameterValues("notifyWay") == null) ? new String[0]
              : request.getParameterValues("notifyWay");

          if (notifyWayString.length > 0) {
            StringBuffer str = new StringBuffer();

            for (int i = 0; i < notifyWayString.length; i++) {
              str.append(notifyWayString[i]).append(",");
            }

            calendarRecord.setNotifyWay(str.toString());
          }

          newUpdateAlert = this.createUpdateAlert(request,
              calendarRecord, alertManager);

          if (newUpdateAlert != null) {
            calendarRecord.setUpdateAlertID(newUpdateAlert.getID());
          }
        }

        //REMINDER HANDLING
        if (((tmpForm.getEmailReminder() != null)
            || (tmpForm.getSystemReminder() != null))&&!Utility.isEmpty(tmpForm.getStartDate())) {
          //Use public AlertManager to control
          UpdateAlert updateAlert = new UpdateAlert();
          updateAlert.setObjectType(UpdateAlert.CALENDAR_TYPE);
          updateAlert.setObjectID(calendarRecord.getID());
          alertManager.newReminderAlert(updateAlert, UpdateAlert.CALENDAR_TYPE,
              calendarRecord.getID(), calendarRecord);
        }

        //recurring record
        if (calendarRecord.getIsRecurrence() != null) {
          this.createRecurringRecord(calendarRecord, sessionContainer,
              connection);
        }

        tmpForm.setFormData(calendarRecord);
        tmpForm.setDatetime(calendarRecord.getDatetime());
        tmpForm.setEndtime(calendarRecord.getEndtime());
      }

      //refreshList(request, GlobalConstant.OP_MODE_INSERT, calendarRecord,
      // list);
    } catch (ApplicationException appe) {
      throw appe;
    } catch (Exception e) {
      log.error("Retrieve calendar record information.", e);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR, e);
    }

    this.selectRecord(mapping, form, request, response);

    connection = null;
  }

  /**
   * updateRecord
   * 
   * Update calendar record
   * 
   * @param mapping
   * @param form
   * @param request
   * @param response
   * @throws ApplicationException
   */
  public void updateRecord(ActionMapping mapping, AbstractActionForm form,
      HttpServletRequest request, HttpServletResponse response)
      throws ApplicationException {
    Connection connection = this.getConnection(request);

    try {
      SessionContainer sessionContainer = this.getSessionContainer(request);
      CalendarRecordDAObject calendarRecordDAO = new CalendarRecordDAObject(
          sessionContainer, connection);
      AlertManager am = new AlertManager(sessionContainer, connection);
      MaintCalendarRecordForm tmpForm = (MaintCalendarRecordForm) form;
      tmpForm = (MaintCalendarRecordForm) form;
      int minuteInterval = SystemParameterFactory.getSystemParameterInteger(SystemParameterConstant.CALENDAR_DEFAULT_TIMEPICKER_INTERVAL).intValue();
      if (tmpForm.getSubMeetingNum() > 1) {
        updateSubCalendar(mapping, form, request, response);
      } else {
        //reset the starttime and endtime if it is a wholeday event
        if ("Y".equals(tmpForm.getIsWholeDay())) {
          tmpForm.setStartHour("00");
          tmpForm.setStartMinute("00");
          tmpForm.setEndHour("23");
          tmpForm.setEndMinute(String.valueOf(60-minuteInterval));
        }
        //estimate the calendar if not same as old calendar
        Integer ID = new Integer(Integer.parseInt(tmpForm.getID()));
        CalendarRecord oldRecord = (CalendarRecord) calendarRecordDAO
            .getObjectByID(ID);
        boolean notModify = false;
        if (!Utility.isEmpty(oldRecord)) {
          if (!Utility.isEmpty(oldRecord.getPriority())
              && !Utility.isEmpty(tmpForm.getPriority())
              && !oldRecord.getPriority().equals(tmpForm.getPriority())) {
            notModify = true;
          }
          if (!Utility.isEmpty(oldRecord.getVenue())
              && !Utility.isEmpty(tmpForm.getVenue())
              && !oldRecord.getVenue().equals(tmpForm.getVenue())) {
            notModify = true;
          }
          if (!Utility.isEmpty(oldRecord.getDetail())
              && !Utility.isEmpty(tmpForm.getDetail())
              && !oldRecord.getDetail().equals(tmpForm.getDetail())) {
            notModify = true;
          }

          /*
           * if(!Utility.isEmpty(oldRecord.getTitle())&&!Utility.isEmpty(tmpForm.getTitle())&&!oldRecord.getTitle().equals(tmpForm.getTitle()) ){
           * notModify = true; }
           * if(!Utility.isEmpty(oldRecord.getPriority())&&!Utility.isEmpty(tmpForm.getPriority())&&!oldRecord.getPriority().equals(tmpForm.getPriority()) ){
           * notModify = true; }
           * if(!Utility.isEmpty(oldRecord.getIsWholeDay())&&!Utility.isEmpty(tmpForm.getIsWholeDay())&&!oldRecord.getIsWholeDay().equals(tmpForm.getIsWholeDay()) ){
           * notModify = true; }
           * if(!Utility.isEmpty(oldRecord.getVenue())&&!Utility.isEmpty(tmpForm.getVenue())&&!oldRecord.getVenue().equals(tmpForm.getVenue()) ){
           * notModify = true; }
           * if(!Utility.isEmpty(oldRecord.getDetail())&&!Utility.isEmpty(tmpForm.getDetail())&&!oldRecord.getDetail().equals(tmpForm.getDetail()) ){
           * notModify = true; }
           */
          if (!Utility.isEmpty(oldRecord.getDatetime())
              && !Utility.isEmpty(tmpForm.getDatetime())
              && !oldRecord.getDatetime().equals(tmpForm.getDatetime())) {
            notModify = true;
          }
          if (!Utility.isEmpty(oldRecord.getEndtime())
              && !Utility.isEmpty(tmpForm.getEndtime())
              && !oldRecord.getEndtime().equals(tmpForm.getEndtime())) {
            notModify = true;
          }

        }
        
        //Merge the change/new meeting messages, So set notModify=false
        notModify=false;//WHY?AND Did the code above use for?
        
        tmpForm.setReminderType(((tmpForm.getEmailReminder() == null) ? ""
            : tmpForm.getEmailReminder())
            + ","
            + ((tmpForm.getSystemReminder() == null) ? "" : tmpForm
                .getSystemReminder()));


        ArrayList re = new ArrayList();
        re.add(tmpForm.getFormData());
        if (!Utility.isEmpty(tmpForm.getIsRecurrence()) && tmpForm.getIsRecurrence().equals("Y")){
        	try{
            re.addAll(selfTimeConflict(sessionContainer,connection,tmpForm));
        	} catch (ApplicationException e){
            log.error("CalendarRecord self conflict.", e);
            throw e;
        	} catch (Exception e){
        		log.error(e);
        		throw e;
        	}
        }

        if (!"true"
            .equals(SystemParameterFactory
                .getSystemParameter(SystemParameterConstant.CALENDAR_ALLOW_OVERLAP))) {
          if (!CalendarRecord.EVENT_TYPE_CALENDAR_TODO.equals(tmpForm
              .getEventType())) {
            /*
             * if (overlapWithOthers(request, form, new Integer(form.getID()))) {
             * throw new
             * ApplicationException(ErrorConstant.CALENDAR_OVERLAP_ERROR); }
             */
            String overlap = "yes";
            if (!Utility.isEmpty(request.getParameter("Overlap"))) {
              overlap = request.getParameter("Overlap");
            }
            Integer formId = new Integer(Integer.parseInt(tmpForm.getID()));

            if (!Utility.isEmpty(tmpForm.getIsRecurrence()) && tmpForm.getIsRecurrence().equals("Y") && Utility.isEmpty(tmpForm.getRecurEndDate())){
            	overlap = "no";
            }
            
            if ("yes".equals(overlap)) {
            	//Update By Jim.Zhou			2006/06/30			Bug	#3950
              //ArrayList overlapList = getOverlapList(request, form, formId);
            	ArrayList overlapList = this.getAllOverlapList(request, form, new Integer(0),re);
            	//Update End
              //if (overlapWithOthers(request, form, null)) {
              if (overlapList.size() > 0) {
                request.setAttribute("overlapList", overlapList);
                String[] userRecords = null;
                String[] userRoles = null;
                String[] userGroups = null;
                userRecords = request.getParameterValues("userRecords");
                userRoles = request.getParameterValues("userRoles");
                userGroups = request.getParameterValues("userGroups");

                tmpForm.setUserList(userRecords);
                tmpForm.setRoleList(userRoles);
                tmpForm.setGroupList(userGroups);
                throw new ApplicationException(
                    ErrorConstant.CALENDAR_OVERLAP_ERROR);
              }
            }

          }
        }
        //"Recurring Start date" should not be allowed to set prior to the "Due
        // Date"
        //  Timestamp strCurrentDate = new Timestamp(new
        // Date(TextUtility.formatTimestamp(Utility.getCurrentTimestamp()))) ;
        Timestamp strCurrentDate = Utility.getCurrentTimestamp();

        //because the strCurrentDate have hh - mm -ss, so getRecurStartDate add
        // 1
        /*if (!Utility.isEmpty(tmpForm.getIsRecurrence())
            && strCurrentDate.after(Utility.addDay(tmpForm
                .formateStringToTimestamp(tmpForm.getRecurStartDate()), 1))) {
          throw new ApplicationException(
              ErrorConstant.CALENDAR_RECURRING_START_DATE_PRIORDUEDATE_ERROR);
        }*/

        //"Recurring End date" should not be allowed to set prior to the
        // "Recurring Start Date"
        if (tmpForm.getRecurEndDate() != null) {
        	tmpForm.setRecurEndDate(tmpForm.getRecurEndDate().replaceAll("00:00:00","23:55:00"));
          if (tmpForm.formateStringToTimestamp(tmpForm.getRecurStartDate())
              .after(
                  tmpForm.formateStringToTimestamp(tmpForm.getRecurEndDate()))) {
            throw new ApplicationException(
                ErrorConstant.CALENDAR_RECURRING_RANGE_ERROR);
          }
        }

        CalendarRecord calendarRecord = (CalendarRecord) calendarRecordDAO
            .getObjectByID(TextUtility.parseIntegerObj(tmpForm.getID()));
        CalendarRecord calendarRecord1 = (CalendarRecord) form.getFormData();
        calendarRecord1.setUpdateCount(calendarRecord.getUpdateCount());

        calendarRecord = (CalendarRecord) calendarRecordDAO
            .updateObject(calendarRecord1);

        calendarRecord.setAlertSubject(calendarRecord1.getAlertSubject());//ADD By TC
        //REMINDER HANDLING
        AlertManager alertManager = new AlertManager(sessionContainer,
            connection);
        UpdateAlert updateAlert = alertManager
            .getUpdateAlertByObjectTypeObjectID(UpdateAlert.CALENDAR_TYPE,
                calendarRecord.getID());

        if (((tmpForm.getEmailReminder() != null)||(tmpForm.getSystemReminder() != null))
                &&!Utility.isEmpty(tmpForm.getStartDate())) {
          if (!Utility.isEmpty(updateAlert)) {
            //updateReminderAlert
            try {
              alertManager.updateReminderAlert(UpdateAlert.CALENDAR_TYPE,
                  calendarRecord.getID(), calendarRecord, calendarRecord
                      .getEventType());
            } catch (ApplicationException aape) {
            }
          } else {
            UpdateAlert newUpdateAlert = new UpdateAlert();
            newUpdateAlert.setObjectType(UpdateAlert.CALENDAR_TYPE);
            newUpdateAlert.setObjectID(calendarRecord.getID());
            try {
              alertManager.newReminderAlert(newUpdateAlert,
                  UpdateAlert.CALENDAR_TYPE, calendarRecord.getID(),
                  calendarRecord);
            } catch (ApplicationException aape) {
            }
          }
        } else {
          if (!Utility.isEmpty(updateAlert)) {
            alertManager.deleteUpdateAlert(updateAlert);
            alertManager.delScheduleJobNotification(updateAlert);
          }
        }

        //delete permission list be object type and ID
        deletePermissionListByObjectTypeObjectID(sessionContainer, connection,
            calendarRecord);

        if (!(CalendarRecord.SHARE_TYPE_PRIVATE.equals((calendarRecord
            .getShareType())))) {
          tmpForm = this.createCalendarRecordSharing(sessionContainer,
              connection, tmpForm);
        }

        //update alert
        if (CalendarRecord.EVENT_TYPE_CALENDAR_MEETING.equals(calendarRecord
            .getEventType())) {
          calendarRecord = updateUpdateAlert(request, sessionContainer,
              connection, calendarRecord, am, "U", notModify);
        }

        CalendarRecurDAObject calendarRecurDAO = new CalendarRecurDAObject(
            sessionContainer, connection);

        if (calendarRecord.getIsRecurrence() != null) {
          calendarRecurDAO.deleteByCalendarID(calendarRecord.getID());
          createRecurringRecord(calendarRecord, sessionContainer, connection);

          //CalendarRecur oldRecur = (CalendarRecur)
          // calendarRecurDAO.getObjectByCalendarID(calendarRecord.getID());
        }

        form.setFormData(calendarRecord);
      }
      // refreshList(request, GlobalConstant.OP_MODE_UPDATE, calendarRecord);
    } catch (ApplicationException aape) {
      throw aape;
    } catch (Exception e) {
      log.error("Retrieve calendar record information.", e);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR, e);
    }

    this.selectRecord(mapping, form, request, response);
    connection = null;
  }

  /**
   * deleteRecord
   * 
   * delete calendar record
   * 
   * @param mapping
   * @param form
   * @param request
   * @param response
   * @throws ApplicationException
   */
  public void deleteRecord(ActionMapping mapping, AbstractActionForm form,
      HttpServletRequest request, HttpServletResponse response)
      throws ApplicationException {
    Connection conn = this.getConnection(request);
    SessionContainer sessionCtx = this.getSessionContainer(request);
    AlertManager am = new AlertManager(sessionCtx, conn);
    String ID = "-1";
    String[] itemToDel = null;

    try {
      CalendarRecordDAObject calendarRecordDAO = new CalendarRecordDAObject(
          sessionCtx, conn);

      if (request.getParameter("ID") != null) {
        ID = request.getParameter("ID");
      }

      CalendarRecordDAObject calendarDAO = new CalendarRecordDAObject(
          sessionCtx, conn);

      //ActivityRecordDAObject activityDAO = new
      // ActivityRecordDAObject(sessionCtx, conn);
      itemToDel = TextUtility.splitString(ID, "|");

      if (itemToDel != null) {
        if (CalendarRecord.EVENT_TYPE_CALENDAR_TODO.equals(itemToDel[1])
            || CalendarRecord.EVENT_TYPE_CALENDAR_EVENT.equals(itemToDel[1])
            || CalendarRecord.EVENT_TYPE_CALENDAR_MEETING.equals(itemToDel[1])) {
          //calendarDAO.SoftDelete(new Integer(itemToDel[0]));
        }

        //if (CalendarRecord.EVENT_TYPE_CALENDAR_MEETING.equals(itemToDel[1])) {
          UpdateAlertDAObject updateAlertDAO = new UpdateAlertDAObject(
              sessionCtx, conn);
          UpdateAlertSystemLogDAObject updateAlertSystemLogDAO = new UpdateAlertSystemLogDAObject(
              sessionCtx, conn);
          UpdateAlertTypeDAObject updateAlertTypeDAO = new UpdateAlertTypeDAObject(
              sessionCtx, conn);

          UpdateAlert updateAlert = (UpdateAlert) updateAlertDAO
              .getByObjectTypeObjectID(UpdateAlert.CALENDAR_TYPE, new Integer(
                  itemToDel[0]));

          if (!Utility.isEmpty(updateAlert)) {
            List updateAlertTypeList = updateAlertTypeDAO
                .getByUpdateAlertIDByOwnerID(updateAlert.getID(), "ALL",
                    sessionCtx.getUserRecordID());

            for (int i = 0; i < updateAlertTypeList.size(); i++) {
              UpdateAlertType updateAlertType = (UpdateAlertType) updateAlertTypeList
                  .get(i);

              //delete updateAlertSystemLog
              UpdateAlertSystemLog updateAlertSystemLog = (UpdateAlertSystemLog) updateAlertSystemLogDAO
                  .getByUpdateAlertTypeIDActionUserID(updateAlertType.getID(),
                      sessionCtx.getUserRecordID());

              if (!Utility.isEmpty(updateAlertSystemLog)) {
                updateAlertSystemLogDAO.deleteObject(updateAlertSystemLog);
              }

              //delete updateAlertType
              updateAlertTypeDAO.deleteObject(updateAlertType);
            }

            //delete updateAlert
            updateAlertDAO.deleteObject(updateAlert);
          }
        //}

        CalendarRecord calendarRecord = (CalendarRecord) calendarDAO
            .getObjectByID(TextUtility.parseIntegerObj(itemToDel[0]));

        //REMINDER HANDLING
        if ((calendarRecord.getReminderType() != null)) {
          updateAlert = new UpdateAlert();
          updateAlert.setObjectType(UpdateAlert.CALENDAR_TYPE);
          updateAlert.setObjectID(calendarRecord.getID());
          updateAlert.setCreatorName(calendarRecord.getCreatorName());

          List userRecordIDList = new ArrayList(1);
          userRecordIDList.add(sessionCtx.getUserRecordID());

          //Date date = new Date(calendarRecord.getDatetime().getTime());

          try {
            am.delScheduleJobNotification(updateAlert);
          } catch (Exception e) {
          }
        }

        //Recurring
        if (calendarRecord.getIsRecurrence() != null) {
          CalendarRecurDAObject calendarRecurDAO = new CalendarRecurDAObject(
              sessionCtx, conn);
          CalendarRecur calendarRecur = (CalendarRecur) calendarRecurDAO
              .getObjectByCalendarID(calendarRecord.getID());
          calendarRecurDAO.deleteObjectByID(calendarRecur.getID());
        }

        //update alert
        if (CalendarRecord.EVENT_TYPE_CALENDAR_MEETING.equals(calendarRecord
            .getEventType())) {
          calendarRecord = updateUpdateAlert(request, sessionCtx, conn,
              calendarRecord, am, "D", true);
        }
        calendarDAO.deleteObjectByID(calendarRecord.getID());

      }
    } catch (Exception e) {
      log.error("Retrieve calendar record information.", e);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR, e);
    }

    conn = null;
  }

  private boolean overlapWithOthers(HttpServletRequest request,
      AbstractActionForm form, Integer ID) throws ApplicationException {
    Connection conn = this.getConnection(request);

    SessionContainer sessionCtx = this.getSessionContainer(request);
    CalendarRecordDAObject calendarRecordDAO = new CalendarRecordDAObject(
        sessionCtx, conn);

    MaintCalendarRecordForm tmpForm = (MaintCalendarRecordForm) form;
    ArrayList list = (ArrayList) calendarRecordDAO
        .getOverlapListByDatePeriodAndEventTypeAndCalendarID(sessionCtx
            .getUserRecordID(), tmpForm.getDatetime(), tmpForm.getEndtime(),
            new String[] { CalendarRecord.EVENT_TYPE_CALENDAR_MEETING,
                CalendarRecord.EVENT_TYPE_CALENDAR_EVENT }, ID, null);

    conn = null;

    if (list.size() > 0) {
      return true;
    } else {
      return false;
    }
  }

  /**
   * refreshFormData
   * 
   * refresh the data of form
   * 
   * @param mapping
   * @param form
   * @param request
   * @param response
   * @throws ApplicationException
   */
  public void refreshFormData(ActionMapping mapping, ActionForm form,
      HttpServletRequest request, HttpServletResponse response)
      throws ApplicationException {
    //    MaintCalendarRecordForm tmpForm = (MaintCalendarRecordForm) form;
    Connection conn = this.getConnection(request);
    HttpSession session = request.getSession();
    String opMode = request.getParameter("opMode");
    int submeetingMaxNum = Integer
        .parseInt(SystemParameterFactory
            .getSystemParameter(SystemParameterConstant.CALENDAR_SUBMEETING_MAXNUM));

    //AbstractSearchForm searchForm = new SearchForm();
    try {
      SessionContainer sessionCtx = (this.getSessionContainer(request) != null) ? this
          .getSessionContainer(request)
          : new SessionContainer();
          CalendarRecordDAObject calendarRecordDAO = new CalendarRecordDAObject(
                sessionCtx, conn);
      MaintCalendarRecordForm mainCalendarRecordForm = (MaintCalendarRecordForm) form;
      
      CalendarRecord calendarRecord = (CalendarRecord) mainCalendarRecordForm
          .getFormData();
      String targetDate = request.getParameter("startDate");
      String popSearchInvite = (String) session.getAttribute("popSearchInvite");

      //Set Header Form data
      //String dummy_display_referenceID =
      // request.getParameter("dummy_display_referenceID");
      //request.getSession().setAttribute("dummy_display_referenceID",
      // dummy_display_referenceID);
      //      mainCalendarRecordForm.setFormData(calendarRecord);
      //      mainCalendarRecordForm.setDatetime(calendarRecord.getDatetime());
      //      mainCalendarRecordForm.setEndtime(calendarRecord.getEndtime());
      //set invite userRecords,userGroups,userRoles
      //get update alert recipient
      List recipientAry = new ArrayList();
      MtmUpdateAlertRecipientDAObject updateRecipientDAO = new MtmUpdateAlertRecipientDAObject(
          sessionCtx, conn);

      // Get all recipients.
      String recipientType = null;
      String[] tmprecipientAry = new String[0];

      if (!Utility.isEmpty(mainCalendarRecordForm.getUpdateAlertID())) {
        recipientAry = updateRecipientDAO.getByUpdateAlertID(new Integer(
            mainCalendarRecordForm.getUpdateAlertID()));
      }

      tmprecipientAry = new String[recipientAry.size()];

      String[] userRecords = new String[recipientAry.size()];
      String[] userGroups = new String[recipientAry.size()];
      String[] userRoles = new String[recipientAry.size()];

      for (int i = 0; i < recipientAry.size(); i++) {
        MtmUpdateAlertRecipient tmprecipient = (MtmUpdateAlertRecipient) recipientAry
            .get(i);

        if (tmprecipient.getRecipientType().equals(UpdateAlert.USER_RECIPIENT)) {
          userRecords[i] = tmprecipient.getRecipientID().toString();
        } else if (tmprecipient.getRecipientType().equals(
            UpdateAlert.GROUP_RECIPIENT)) {
          userGroups[i] = tmprecipient.getRecipientID().toString();
        } else if (tmprecipient.getRecipientType().equals(
            UpdateAlert.ROLE_RECIPIENT)) {
          userRoles[i] = tmprecipient.getRecipientID().toString();
        }
      }

      if (Utility.isEmpty(request.getSession().getAttribute("recipientType"))) {
        //        if (!"true".equals(popSearchInvite)){
        mainCalendarRecordForm.setUserList(userRecords);
        mainCalendarRecordForm.setGroupList(userGroups);
        mainCalendarRecordForm.setRoleList(userRoles);
      } else {
        recipientType = (String) request.getSession().getAttribute(
            "recipientType");
        tmprecipientAry = (String[]) request.getSession().getAttribute(
            "recipientRecords");
        userRecords = null;
        userGroups = null;
        userRoles = null;

        if (UpdateAlert.USER_RECIPIENT.equals(recipientType)) {
          userRecords = tmprecipientAry;
        } else if (UpdateAlert.GROUP_RECIPIENT.equals(recipientType)) {
          userGroups = tmprecipientAry;
        } else if (UpdateAlert.ROLE_RECIPIENT.equals(recipientType)) {
          userRoles = tmprecipientAry;
        }

        mainCalendarRecordForm.setUserList(userRecords);
        mainCalendarRecordForm.setGroupList(userGroups);
        mainCalendarRecordForm.setRoleList(userRoles);
        request.getSession().setAttribute("recipientType", null);
        mainCalendarRecordForm.setEndDate(null);
        mainCalendarRecordForm.setStartDate(null);
      }
      //mainCalendarRecordForm.setFormData(calendarRecord);
      //mainCalendarRecordForm.setDatetime(calendarRecord.getDatetime());
      //mainCalendarRecordForm.setEndtime(calendarRecord.getEndtime());
      //submeeting
      //account between startDate and endDate
      if (!Utility.isEmpty(mainCalendarRecordForm.getStartDate())
          && !Utility.isEmpty(mainCalendarRecordForm.getEndDate())) {
        int dateCount = 0;
        String dateString = null;
        int subMeetingNum = mainCalendarRecordForm.getSubMeetingNum();
        String refreshIntervalDays = mainCalendarRecordForm.getRefreshIntervalDays();
        
        java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat(
            SystemParameterFactory.getSystemParameter(
                SystemParameterConstant.DB_DATETIME_FORMAT).substring(0, 10));
        java.util.Date d1 = formatter.parse(mainCalendarRecordForm
            .getStartDate());
        java.util.Date d2 = formatter
            .parse(mainCalendarRecordForm.getEndDate());
        dateCount = (int) ((d2.getTime() - d1.getTime()) / 86400000);
        dateCount++;
        if("Y".equals(refreshIntervalDays)){
          if (dateCount <= submeetingMaxNum){
            mainCalendarRecordForm.setSubMeetingNum(dateCount);
          }            
          else {
            mainCalendarRecordForm.setSubMeetingNum(0);
            throw new ApplicationException("error.calendar.exceed.maxsubmeeting");
          }
        } else {
        	if(subMeetingNum<=0){
        		subMeetingNum=1;
        	}
          d2.setTime(d1.getTime()+86400000*(subMeetingNum-1));
          mainCalendarRecordForm.setEndDate(formatter.format(d2));
        }
        
      }
      List subList = null;
      if (!Utility.isEmpty(calendarRecord.getParentID())) {
        subList = calendarRecordDAO.getListByParentID(calendarRecord
            .getParentID().toString());        
        request.setAttribute("subList", subList);
      }

    } catch (ApplicationException e) {
      log.error("Retrieve calendar record information.", e);
      handleApplicationException(request, e);
    } catch (Exception e) {
      log.error("Retrieve calendar record information.", e);
      handleApplicationException(request, new ApplicationException(e));
    }

    conn = null;
  }

  /**
   * replyOnInvite
   * 
   * reply on invite
   * 
   * @param mapping
   * @param form
   * @param request
   * @param response
   * @throws ApplicationException
   */
  public void replyOnInvite(ActionMapping mapping, ActionForm form,
      HttpServletRequest request, HttpServletResponse response)
      throws ApplicationException {
    Connection connection = this.getConnection(request);

    try {
      SessionContainer sessionContainer = this.getSessionContainer(request);
      CalendarRecordDAObject calendarRecordDAO = new CalendarRecordDAObject(
          sessionContainer, connection);
      CalendarRetrievalManager calendarRetrievalManager = new CalendarRetrievalManager(sessionContainer,connection);
      
      CalendarRecurDAObject calendarRecurDAO = new CalendarRecurDAObject(sessionContainer, connection);
      
      MaintCalendarRecordForm tmpForm = (MaintCalendarRecordForm) form;
      CalendarRecord calendarRecord = (CalendarRecord) tmpForm.getFormData();
      calendarRecord = (CalendarRecord) calendarRecordDAO
          .getObjectByID(calendarRecord.getID());

      CalendarRecur calendarRecur = (CalendarRecur)calendarRecurDAO.getObjectByCalendarID(calendarRecord.getID());
      
      
      tmpForm.setStartDate(calendarRecord.getDatetime().toString().substring(0,
          19));
      tmpForm.setEndDate(calendarRecord.getEndtime().toString()
          .substring(0, 19));

      tmpForm.setStartHour(calendarRecord.getDatetime().toString().substring(
          11, 13));
      tmpForm.setEndHour(calendarRecord.getEndtime().toString().substring(11,
          13));
      tmpForm.setStartMinute(calendarRecord.getDatetime().toString().substring(
          14, 16));
      tmpForm.setEndMinute(calendarRecord.getEndtime().toString().substring(14,
          16));
      calendarRecord = (CalendarRecord) tmpForm.getFormData();

      Integer systemLogID = null;
      if (!Utility.isEmpty(request.getParameter("systemLogID"))) {
          systemLogID = new Integer(Integer.parseInt(request
              .getParameter("systemLogID")));
        }
      String replyType = (request.getParameter("replyType") == null) ? ""
              : request.getParameter("replyType");


      /*
       *	Update Code Start
       *	Author				Jim.Zhou
       *	Date					2006/06/05
       *	Bug						#3950
       */
      if ("A".equals(replyType)){
        String[] userRecords = null;
        String[] userRoles = null;
        String[] userGroups = null;

        userRecords = request.getParameterValues("userRecords");
        userRoles = request.getParameterValues("userRoles");
        userGroups = request.getParameterValues("userGroups");
        
        ArrayList re = new ArrayList();
        MaintCalendarRecordForm tmpMaintForm = new MaintCalendarRecordForm();
        tmpMaintForm.setFormData(calendarRecordDAO.getByID(calendarRecord.getID()));
        re.add(calendarRecord);
        if (!Utility.isEmpty(tmpMaintForm.getIsRecurrence()) && tmpMaintForm.getIsRecurrence().equals("Y")){
          ArrayList recurList = new ArrayList();
          recurList.add(calendarRecord);
          re.addAll(calendarRetrievalManager
          							.createVirtualRecordForRecurring(sessionContainer,
          									connection,
          									recurList,
          									((MaintCalendarRecordForm)form).getDatetime(),
          									((MaintCalendarRecordForm)form).getEndtime(),
          									"M",
          									"R"));
        }
        
        String overlap = "yes";
        if (!Utility.isEmpty(request.getParameter("Overlap"))) {
          overlap = request.getParameter("Overlap");
        }
        
        if (!Utility.isEmpty(calendarRecur) && Utility.isEmpty(calendarRecur.getEndDate())){
        	overlap = "no";
        }

        //check overlap with others
        if ("yes".equals(overlap)
            && !"true"
                .equals(SystemParameterFactory
                    .getSystemParameter(SystemParameterConstant.CALENDAR_ALLOW_OVERLAP))) {
          if (!CalendarRecord.EVENT_TYPE_CALENDAR_TODO.equals(tmpForm
              .getEventType())
              && (tmpForm.getEventType() != null)) {
          	//Update By Jim.Zhou		2006/06/30			Bug	#3950
          	//Ryan: overlap checking logic rollback
            ArrayList overlapList = getOverlapList(request, (AbstractActionForm)form,new Integer(0));
            //ArrayList overlapList = this.getAllOverlapList(request,(AbstractActionForm)form,new Integer(0),re);
          	//Update End
            //if (overlapWithOthers(request, form, null)) {
            
            if (overlapList.size() > 0) {
              request.setAttribute("overlapList", overlapList);
              //tmpForm.setUserList(userRecords);
              //tmpForm.setRoleList(userRoles);
              //tmpForm.setGroupList(userGroups);
              throw new ApplicationException(ErrorConstant.CALENDAR_OVERLAP_ERROR);
            }
            
          }
        }
      }
      
     if (UpdateAlert.ACCEPT_ON_REPLY.equals(replyType)) {
       try{
        String recipientType=GlobalConstant.OBJECT_TYPE_UDF;
        UpdateAlertSystemLogDAObject updateAlertSystemLogDAO=new UpdateAlertSystemLogDAObject(sessionContainer, connection);
        UpdateAlertSystemLog tmpUpdateAlertSystemLog=(UpdateAlertSystemLog)updateAlertSystemLogDAO.getObjectByID(systemLogID);
        UpdateAlertTypeDAObject updateAlertTypeDAO=new UpdateAlertTypeDAObject(sessionContainer, connection);
        UpdateAlertType tmpUpdateAlertType=(UpdateAlertType)updateAlertTypeDAO.getObjectByID(tmpUpdateAlertSystemLog.getUpdateAlertTypeID());
        Integer recipientID=sessionContainer.getUserRecordID();
        Integer update_alert_id=tmpUpdateAlertType.getUpdateAlertID();
        tmpUpdateAlertType=(UpdateAlertType)updateAlertTypeDAO.getIDByUpdateAlertIDAndActionType(update_alert_id,UpdateAlert.REMIND_ACTION);
         if(tmpUpdateAlertType!=null){
          Integer update_alert_type_id_r=tmpUpdateAlertType.getID();
          MtmUpdateAlertRecipientDAObject mtmAlertRecipientDAO=new MtmUpdateAlertRecipientDAObject(sessionContainer, connection);
          MtmUpdateAlertRecipient recipient = (MtmUpdateAlertRecipient)mtmAlertRecipientDAO.getByRecipientIDs(recipientID,recipientType,update_alert_id,update_alert_type_id_r);
          mtmAlertRecipientDAO.updateByID(recipient.getID());
         }
       }catch(Exception e){
         
       }
        
      }
	     /*
	      *	Update Code End
	      */

      if (CalendarRecord.EVENT_TYPE_CALENDAR_MEETING.equals(calendarRecord
          .getEventType())) {
        //String replyType = (request.getParameter("replyType") == null) ? "": request.getParameter("replyType");

        // create UpdateAlert on reply
        AlertManager alertManager = new AlertManager(sessionContainer,
            connection);
        alertManager.createUpdateAlertSystemLog(calendarRecord
            .getUpdateAlertID(), calendarRecord.getID(), replyType);

        if (!UpdateAlert.TENTATIVE_ON_REPLY.equals(replyType)) {
        	/*
          Integer systemLogID = null;

          if (!Utility.isEmpty(request.getParameter("systemLogID"))) {
            systemLogID = new Integer(Integer.parseInt(request
                .getParameter("systemLogID")));
          }
           */

          setSystemLogToRead(systemLogID, request);
          /*
           * if (systemLogID != null) { if
           * (alertManager.checkForSystemLogActionByActionType( systemLogID,
           * UpdateAlertLogAction.READ_ACTION)) { //Got READ record; Can go
           * delete the READ reocrd to mark as un-read
           * alertManager.deleteLogActionBySystemLogID(systemLogID); }
           * 
           * //Go create read record UpdateAlertSystemLog systemLog = new
           * UpdateAlertSystemLog(); systemLog.setID(systemLogID);
           * alertManager.createSystemLogAction(systemLog,
           * UpdateAlertLogAction.READ_ACTION, null, null); }
           */
        }
      }

      connection.commit();
      tmpForm.setFormData(calendarRecord);

      //refreshList(request, GlobalConstant.OP_MODE_INSERT, calendarRecord);
    } catch (ApplicationException appe) {
      throw appe;
    } catch (Exception e) {
      log.error("Retrieve calendar record information.", e);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR, e);
    }

    connection = null;
  }

  private MaintCalendarRecordForm createCalendarRecordSharing(
      SessionContainer sessionContainer, Connection connection,
      MaintCalendarRecordForm maintCalendarRecordForm) throws ApplicationException {
    UserRecordPermissionDAObject userPermissionDAObject = new UserRecordPermissionDAObject(
        sessionContainer, connection);
    UserGroupPermissionDAObject groupPermissionDAObject = new UserGroupPermissionDAObject(
        sessionContainer, connection);
    UserRolePermissionDAObject rolePermissionDAObject = new UserRolePermissionDAObject(
        sessionContainer, connection);

    //Set allUserIDSet = new HashSet();
    //save all selected user permission from user list
    String[] userIDsToShare = (maintCalendarRecordForm.getUserIDsToShare() == null) ? new String[0]
        : maintCalendarRecordForm.getUserIDsToShare();

    for (int j = 0; j < userIDsToShare.length; j++) {
      if ((userIDsToShare[j] != null) && !"".equals(userIDsToShare[j])) {
        UserRecordPermission userPermission = new UserRecordPermission();
        userPermission.setUserRecordID(TextUtility
            .parseIntegerObj(userIDsToShare[j]));
        userPermission.setObjectType(GlobalConstant.OBJECT_TYPE_CALENDAR);
        userPermission.setObjectID(new Integer(maintCalendarRecordForm.getID()));

        if (CalendarRecord.SHARE_TYPE_PUBLIC.equals(maintCalendarRecordForm
            .getShareType())) {
          userPermission.setPermission(PERMISSION_READONLY);
        } else if (CalendarRecord.SHARE_TYPE_SHOW_TITLE.equals(maintCalendarRecordForm
            .getShareType())) {
          userPermission.setPermission(PERMISSION_READ_TITLE_ONLY);
        }

        userPermission.setCanGrant(GlobalConstant.FALSE);
        userPermissionDAObject.insertObject(userPermission);
      }
    }

    //save all selected group permissiond from group list
    String[] groupIDsToShare = (maintCalendarRecordForm.getGroupIDsToShare() == null) ? new String[0]
        : maintCalendarRecordForm.getGroupIDsToShare();

    for (int j = 0; j < groupIDsToShare.length; j++) {
      if ((groupIDsToShare[j] != null) && !"".equals(groupIDsToShare[j])) {
        UserGroupPermission groupPermission = new UserGroupPermission();
        groupPermission.setUserGroupID(TextUtility
            .parseIntegerObj(groupIDsToShare[j]));
        groupPermission.setObjectType(GlobalConstant.OBJECT_TYPE_CALENDAR);
        groupPermission.setObjectID(new Integer(maintCalendarRecordForm.getID()));

        if (CalendarRecord.SHARE_TYPE_PUBLIC.equals(maintCalendarRecordForm
            .getShareType())) {
          groupPermission.setPermission(PERMISSION_READONLY);
        } else if (CalendarRecord.SHARE_TYPE_SHOW_TITLE.equals(maintCalendarRecordForm
            .getShareType())) {
          groupPermission.setPermission(PERMISSION_READ_TITLE_ONLY);
        }

        groupPermission.setCanGrant(GlobalConstant.FALSE);
        groupPermissionDAObject.insertObject(groupPermission);
      }
    }

    //save all selected role permission from role list
    String[] roleIDsToShare = (maintCalendarRecordForm.getRoleIDsToShare() == null) ? new String[0]
        : maintCalendarRecordForm.getRoleIDsToShare();

    for (int j = 0; j < roleIDsToShare.length; j++) {
      if ((roleIDsToShare[j] != null) && !"".equals(roleIDsToShare[j])) {
        UserRolePermission rolePermission = new UserRolePermission();
        rolePermission.setUserRoleID(TextUtility
            .parseIntegerObj(roleIDsToShare[j]));
        rolePermission.setObjectType(GlobalConstant.OBJECT_TYPE_CALENDAR);
        rolePermission.setObjectID(new Integer(maintCalendarRecordForm.getID()));

        if (CalendarRecord.SHARE_TYPE_PUBLIC.equals(maintCalendarRecordForm
            .getShareType())) {
          rolePermission.setPermission(PERMISSION_READONLY);
        } else if (CalendarRecord.SHARE_TYPE_SHOW_TITLE.equals(maintCalendarRecordForm
            .getShareType())) {
          rolePermission.setPermission(PERMISSION_READ_TITLE_ONLY);
        }

        rolePermission.setCanGrant(GlobalConstant.FALSE);
        rolePermissionDAObject.insertObject(rolePermission);
      }
    }

    return maintCalendarRecordForm;
  }

  private void refreshList(HttpServletRequest request, String opMode,
      AbstractBaseObject obj, List list) {
    //java.util.ArrayList list =
    // (java.util.ArrayList)request.getSession().getAttribute(this.listName);
    if (list != null) {
      if (GlobalConstant.OP_MODE_INSERT.equals(opMode)) {
        list.add(obj);
      } else if (GlobalConstant.OP_MODE_UPDATE.equals(opMode)) {
        for (int i = 0; i < list.size(); i++) {
          if (obj.equals(list.get(i))) {
            list.remove(i);
            list.add(i, obj);
          }
        }
      } else if (GlobalConstant.OP_MODE_DELETE.equals(opMode)) {
        for (int i = 0; i < list.size(); i++) {
          if (obj.equals(list.get(i))) {
            list.remove(i);
          }
        }
      }
    }
  }

  private ArrayList getLabelValueByList(List list) {
    ArrayList entries = new ArrayList();
    ArrayList list1 = (ArrayList) list;

    if (list1 != null) {
      for (int i = 0; i < list1.size(); i++) {
        if (list1.get(i) instanceof UserRecord) {
          UserRecord userRecord = (UserRecord) list1.get(i);
          entries.add(new LabelValueBean(userRecord.getFirstName(), userRecord
              .getID().toString()));
        } else if (list1.get(i) instanceof UserGroup) {
          UserGroup userGroup = (UserGroup) list1.get(i);
          entries.add(new LabelValueBean(userGroup.getGroupName(), userGroup
              .getID().toString()));
        } else if (list1.get(i) instanceof UserRole) {
          UserRole userRole = (UserRole) list1.get(i);
          entries.add(new LabelValueBean(userRole.getRoleName(), userRole
              .getID().toString()));
        }
      }
    }

    return entries;
  }

  private void setAllUserGroupRoleAttributes(ActionForm form,
      HttpServletRequest request) throws ApplicationException {
    //set all other user list
    UserRecordDAObject userRecordDAO = new UserRecordDAObject(this
        .getSessionContainer(request), this.getConnection(request));
    List allUserList = userRecordDAO.getAllOtherUserByStatus(
        GlobalConstant.STATUS_ACTIVE, this.getSessionContainer(request)
            .getUserRecordID());
    request.setAttribute("allUserList", allUserList);
  }

  private UpdateAlert createUpdateAlert(HttpServletRequest request,
      CalendarRecord calendarRecord, AlertManager alertManager)
      throws ApplicationException {
    UpdateAlert newUpdateAlert = null;
    String[] userRecords = null;
    String[] userRoles = null;
    String[] userGroups = null;

    String alertSubject = (request.getParameter("alertSubject") == null) ? ""
        : request.getParameter("alertSubject");
    String recipientType = (request.getParameter("recipientType") == null) ? ""
        : request.getParameter("recipientType");
    String[] notifyWayString = (request.getParameterValues("notifyWay") == null) ? new String[0]
        : request.getParameterValues("notifyWay");

    if (notifyWayString.length > 0) {
      UpdateAlert updateAlert = new UpdateAlert();
      updateAlert.setObjectType(UpdateAlert.CALENDAR_TYPE);
      updateAlert.setObjectID(calendarRecord.getID());

      StringBuffer str = new StringBuffer();

      for (int i = 0; i < notifyWayString.length; i++) {
        str.append(notifyWayString[i] + ",");
      }

      userRecords = request.getParameterValues("userRecords");
      userRoles = request.getParameterValues("userRoles");
      userGroups = request.getParameterValues("userGroups");

      /*
       * userRecords = request.getParameterValues("userList"); userGroups =
       * request.getParameterValues("groupList"); userRoles =
       * request.getParameterValues("roleList");
       *  
       */
      /*
       * if (UpdateAlert.USER_RECIPIENT.equals(recipientType)) { userRecords =
       * request.getParameterValues("userRecords"); } else if
       * (UpdateAlert.GROUP_RECIPIENT.equals(recipientType)) { userGroups =
       * request.getParameterValues("userGroups"); } else if
       * (UpdateAlert.ROLE_RECIPIENT.equals(recipientType)) { userRoles =
       * request.getParameterValues("userRoles"); }
       */
      MtmUpdateAlertRecipient[] tmpRecipients = alertManager.getRecipient(
          userRecords, userGroups, userRoles);

      //get the notifyUserIDList
      List notifyUserIDList = alertManager.getDistinctUserIDListByLists(
          userRecords, userGroups, userRoles);

      /*
       * Update Code Start
       * Author					Jim.Zhou
       * Date						2006/06/01
       * Bug						#5572
       */
      //Filter notifyUserIDList
      if (notifyUserIDList.indexOf(calendarRecord.getCreatorID())<0){
        notifyUserIDList.remove(calendarRecord.getCreatorID());
      }
      /*
       * Update Code End
       */

      // create UpdateAlert
      String[] actionTypes = new String[1];
      actionTypes[0] = "I";

      //      actionTypes[0] = "R";
      UpdateAlertType[] updateTypes = new UpdateAlertType[actionTypes.length];

      for (int i = 0; i < actionTypes.length; i++) {
        UpdateAlertType alertUpdateType = new UpdateAlertType();
        alertUpdateType.setUpdateAlertID(updateAlert.getID());
        alertUpdateType.setActionType(actionTypes[i]);
        alertUpdateType.setNeedReply("Y");
        alertUpdateType.setNotifyWay(str.toString());
        alertUpdateType.setAlertSubject(alertSubject);
        updateTypes[i] = alertUpdateType;
      }

      /*
       * newUpdateAlert = (UpdateAlert) alertManager.createUpdateAlert(
       * updateAlert, updateTypes, null, tmpRecipients);
       */
      newUpdateAlert = alertManager.createUpdateAlert(
          updateAlert, updateTypes, tmpRecipients, null, null, calendarRecord
              .getDatetime(), calendarRecord.getTitle(), calendarRecord
              .getCreatorID(), notifyUserIDList);
    }

    return newUpdateAlert;
  }

  private void createRecurringRecord(CalendarRecord calendarRecord,
      SessionContainer sessionCtx, Connection conn) throws ApplicationException {

    CalendarRecur calendarRecur = new CalendarRecur();
    calendarRecur.setCalendarID(calendarRecord.getID());
    calendarRecur.setStartDate(calendarRecord.getRecurStartDate());
    calendarRecur.setEndDate(calendarRecord.getRecurEndDate());
    calendarRecur.setRepeatTimes(calendarRecord.getRepeatTimes());
    calendarRecur.setRecurType(calendarRecord.getRecurType());
    calendarRecur.setRepeatOn(calendarRecord.getRepeatOn());
    calendarRecur.setRepeatType(calendarRecord.getRepeatType());
    calendarRecur.setRepeatTypeDay(calendarRecord.getRepeatTypeDay());
    calendarRecur.setOccurType(calendarRecord.getOccurType());
    calendarRecur.setOccurWeekDay(calendarRecord.getOccurWeekDay());
    calendarRecur.setOccurMonth(calendarRecord.getOccurMonth());
    calendarRecur.setRecordStatus(GlobalConstant.STATUS_ACTIVE);

    CalendarRecurDAObject calendarRecurDAO = new CalendarRecurDAObject(
        sessionCtx, conn);
    calendarRecurDAO.insertObject(calendarRecur);
  }

  private MaintCalendarRecordForm setFormDate(MaintCalendarRecordForm tmpForm) {

    tmpForm.setEndDate(tmpForm.getEndDate());

    StringBuffer fullTime = new StringBuffer();
    fullTime.append(tmpForm.getStartDate()).append(" ").append(
        (tmpForm.getEndHour() == null) ? "0" : tmpForm.getEndHour())
        .append(":").append(
            (tmpForm.getEndMinute() == null) ? "0" : tmpForm.getEndMinute())
        .append(":").append("00");

    java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat(
        SystemParameterFactory
            .getSystemParameter(SystemParameterConstant.DB_DATETIME_FORMAT),
        new java.util.Locale(SystemParameterFactory
            .getSystemParameter(SystemParameterConstant.LOCALE)));
    Date tempDate = null;

    try {
      tempDate = formatter.parse(fullTime.toString());
      tmpForm.setEndtime(new Timestamp(tempDate.getTime()));
    } catch (java.text.ParseException pe) {
      tempDate = null;
    }

    return tmpForm;
  }

  private void deletePermissionListByObjectTypeObjectID(
      SessionContainer sessionContainer, Connection connection,
      CalendarRecord calendarRecord) throws ApplicationException {
    UserRecordPermissionDAObject userPermissionDAObject = new UserRecordPermissionDAObject(
        sessionContainer, connection);
    UserGroupPermissionDAObject groupPermissionDAObject = new UserGroupPermissionDAObject(
        sessionContainer, connection);
    UserRolePermissionDAObject rolePermissionDAObject = new UserRolePermissionDAObject(
        sessionContainer, connection);

    //clear up the old permissions
    userPermissionDAObject.deleteListByObjectTypeObjectIDUpdaterID(
        GlobalConstant.OBJECT_TYPE_CALENDAR, calendarRecord.getID(), sessionContainer.getUserRecordID());
    groupPermissionDAObject.deleteListByObjectTypeObjectIDUpdaterID(
        GlobalConstant.OBJECT_TYPE_CALENDAR, calendarRecord.getID(), sessionContainer.getUserRecordID());
    rolePermissionDAObject.deleteListByObjectTypeObjectIDUpdaterID(
        GlobalConstant.OBJECT_TYPE_CALENDAR, calendarRecord.getID(), sessionContainer.getUserRecordID());
  }

  //

  /**
   * update or delete a meeting if the meeting have invitation ,update the
   * updateAlertlog
   * 
   * 
   * 
   * @param request
   * @param sessionContainer
   * @param request
   * @param connection
   * @param calendarRecord
   * @param am
   * @param type :
   *          "U"update,"D"delete
   * @throws ApplicationException
   */
  private CalendarRecord updateUpdateAlert(HttpServletRequest request,
      SessionContainer sessionContainer, Connection connection,
      CalendarRecord calendarRecord, AlertManager am, String type,
      boolean isModify) throws ApplicationException {
    String recipientType = (request.getParameter("recipientType") == null) ? ""
        : request.getParameter("recipientType");
    String[] notifyWayString = (request.getParameterValues("notifyWay") == null) ? new String[0]
        : request.getParameterValues("notifyWay");
    UpdateAlertDAObject updateAlertDAO = new UpdateAlertDAObject(
        sessionContainer, connection);
    CalendarRetrievalManager calendarRetrievalManager = new CalendarRetrievalManager(sessionContainer,connection);
    if (notifyWayString.length > 0) {

      UpdateAlert updateAlert = new UpdateAlert();

      
      if (calendarRecord.getUpdateAlertID() != null) {
        updateAlert = (UpdateAlert) updateAlertDAO.getObjectByID(calendarRecord
            .getUpdateAlertID());
      } else {
        if (notifyWayString.length > 0) {
          updateAlert.setObjectType(UpdateAlert.CALENDAR_TYPE);
          updateAlert.setObjectID(calendarRecord.getID());

          StringBuffer str = new StringBuffer();

          for (int i = 0; i < notifyWayString.length; i++) {
            str.append(notifyWayString[i]).append(",");
          }

          //updateAlert.setNotifyWay(str.toString());
          calendarRecord.setNotifyWay(str.toString());
        }
      }
      updateAlert.setAlertSubject(calendarRecord.getAlertSubject());//TC.ADD
      StringBuffer str = new StringBuffer();

      for (int i = 0; i < notifyWayString.length; i++) {
        str.append(notifyWayString[i]).append(",");
      }

      //updateAlert.setNotifyWay(str.toString());
      calendarRecord.setNotifyWay(str.toString());

      /*
       * String[] userRecords = request.getParameterValues("userList"); String[]
       * userGroups = request.getParameterValues("groupList"); String[]
       * userRoles = request.getParameterValues("roleList");
       */
      String[] userRecords = request.getParameterValues("userRecords");
      String[] userRoles = request.getParameterValues("userRoles");
      String[] userGroups = request.getParameterValues("userGroups");
      //get the notifyUserIDList
      List notifyUserIDList = am.getDistinctUserIDListByLists(userRecords,
          userGroups, userRoles);
      
      notifyUserIDList.remove(calendarRecord.getCreatorID());
      
      //MtmUpdateAlertRecipient[] tmpRecipients=am.getRecipient(recipientType,
      // userRecords, userRoles, userGroups);
      MtmUpdateAlertRecipient[] tmpRecipients = am.getRecipient(userRecords,
          userGroups, userRoles);
      String[] actionTypes = new String[1];
      actionTypes[0] = "I";

      //      actionTypes[0] = "R";
      UpdateAlertType[] updateTypes = new UpdateAlertType[actionTypes.length];

      for (int i = 0; i < actionTypes.length; i++) {
        UpdateAlertType alertUpdateType = new UpdateAlertType();
        alertUpdateType.setUpdateAlertID(updateAlert.getID());
        alertUpdateType.setNotifyWay(str.toString());
        alertUpdateType.setActionType(actionTypes[i]);
        alertUpdateType.setNeedReply("Y");
        alertUpdateType.setAlertSubject(updateAlert.getAlertSubject());
        updateTypes[i] = alertUpdateType;
      }

      //update
      if ("U".equals(type)) {
        if (calendarRecord.getUpdateAlertID() != null) {
          am.deleteUpdateAlert(updateAlert);
          //am.createUpdateAlert(updateAlert, updateTypes, null,tmpRecipients);
          /*am.createUpdateAlert(updateAlert, updateTypes, tmpRecipients, null,
              null, calendarRecord.getDatetime(), calendarRecord.getTitle(),
              calendarRecord.getCreatorID(), notifyUserIDList);*/
          if (isModify) {
            updateAlert.setObjectType(UpdateAlert.CALENDAR_MODIFY_TYPE);
            //am.createUpdateAlert(updateAlert,
            //updateTypes, tmpRecipients, null, null,
            //calendarRecord.getDatetime(), calendarRecord.getTitle(),
            //calendarRecord.getCreatorID(), notifyUserIDList);
            am.createUpdateAlert(updateAlert, updateTypes, null, tmpRecipients);
            updateAlert.setObjectType(UpdateAlert.CALENDAR_TYPE);
          	am.createUpdateAlert(updateAlert, updateTypes, tmpRecipients, null,
                null, calendarRecord.getDatetime(), calendarRecord.getTitle(),
                calendarRecord.getCreatorID(), notifyUserIDList);
          } else {
          	updateAlert.setObjectType(UpdateAlert.CALENDAR_TYPE);
          	am.createUpdateAlert(updateAlert, updateTypes, tmpRecipients, null,
                    null, calendarRecord.getDatetime(), calendarRecord.getTitle(),
                    calendarRecord.getCreatorID(), notifyUserIDList);
          }
          //am.updateUpdateAlert(updateAlert, updateTypes, tmpRecipients,
          // UpdateAlert.INVITE_TYPE);
        } else {
        	updateAlert.setObjectType(UpdateAlert.CALENDAR_TYPE);
          am.createUpdateAlert(updateAlert, updateTypes, tmpRecipients, null,
              null, calendarRecord.getDatetime(), calendarRecord.getTitle(),
              calendarRecord.getCreatorID(), notifyUserIDList);
          //am.createUpdateAlert(updateAlert, updateTypes, null,tmpRecipients);
        }

        //delete
      } else {
        updateAlert.setObjectType(UpdateAlert.CALENDAR_INACTIVE_TYPE);
        am.createUpdateAlert(updateAlert, updateTypes, null, tmpRecipients);
      }      
      if(!Utility.isEmpty(calendarRecord.getNotifyWay()) && calendarRecord.getNotifyWay().indexOf("E") > 0){
      	calendarRetrievalManager.sendInvitationEmail(connection, sessionContainer, calendarRecord, request, type);
      }
    } else {
      UpdateAlert updateAlert = new UpdateAlert();

      if (calendarRecord.getUpdateAlertID() != null) {
        updateAlert = (UpdateAlert) updateAlertDAO.getObjectByID(calendarRecord
            .getUpdateAlertID());
        am.deleteUpdateAlert(updateAlert);
      }

    }

    return calendarRecord;
  }

  private MaintCalendarRecordForm setUserSharingList(
      SessionContainer sessionContainer, Connection connection,
      CalendarRecord calendarRecord,
      MaintCalendarRecordForm maintCalendarRecordForm)
      throws ApplicationException {
    UserRecordPermissionDAObject userPermissionDAO = new UserRecordPermissionDAObject(
        sessionContainer, connection);
    String[] sharingUserIDs = null;

    //user sharing permission
    UserRecordDAObject userRecordDAO = new UserRecordDAObject(sessionContainer,connection);
    List sharingList = new ArrayList();
    sharingList = userPermissionDAO.getListByObjectTypeObjectIDUpdaterID(GlobalConstant.OBJECT_TYPE_CALENDAR,
              calendarRecord.getID(),sessionContainer.getUserRecordID());
    if (sharingList != null) {
      sharingUserIDs = new String[sharingList.size()];

      for (int i = 0; i < sharingList.size(); i++) {
        sharingUserIDs[i] = ((UserRecordPermission) sharingList.get(i))
            .getUserRecordID().toString();
      }

      maintCalendarRecordForm.setUserIDsToShare(sharingUserIDs);
    }

    return maintCalendarRecordForm;
  }

  private MaintCalendarRecordForm setGroupSharingList(
      SessionContainer sessionContainer, Connection connection,
      CalendarRecord calendarRecord,
      MaintCalendarRecordForm maintCalendarRecordForm)
      throws ApplicationException {
    UserGroupPermissionDAObject groupPermissionDAObject = new UserGroupPermissionDAObject(
        sessionContainer, connection);
    String[] sharingGroupIDs = null;

    //group sharing permission
    UserGroupDAObject userGroupDAO = new UserGroupDAObject(sessionContainer,
        connection);
    List sharingList = new ArrayList();
    sharingList = groupPermissionDAObject.getListByObjectTypeObjectIDUpdaterID(GlobalConstant.OBJECT_TYPE_CALENDAR,
        calendarRecord.getID(),sessionContainer.getUserRecordID());   

    if (sharingList != null) {
      sharingGroupIDs = new String[sharingList.size()];

      for (int i = 0; i < sharingList.size(); i++) {
        sharingGroupIDs[i] = ((UserGroupPermission) sharingList.get(i))
            .getUserGroupID().toString();
      }

      maintCalendarRecordForm.setGroupIDsToShare(sharingGroupIDs);
    }

    return maintCalendarRecordForm;
  }

  private MaintCalendarRecordForm setRoleSharingList(
      SessionContainer sessionContainer, Connection connection,
      CalendarRecord calendarRecord,
      MaintCalendarRecordForm maintCalendarRecordForm)
      throws ApplicationException {
    UserRolePermissionDAObject rolePermissionDAObject = new UserRolePermissionDAObject(
        sessionContainer, connection);
    String[] sharingRoleIDs = null;

    UserRoleDAObject userRoleDAO = new UserRoleDAObject(sessionContainer,
        connection);

    //role sharing permission
    List sharingList = new ArrayList();

    sharingList = rolePermissionDAObject.getListByObjectTypeObjectIDUpdaterID(GlobalConstant.OBJECT_TYPE_CALENDAR,
        calendarRecord.getID(),sessionContainer.getUserRecordID());   


    if (sharingList != null) {
      sharingRoleIDs = new String[sharingList.size()];

      for (int i = 0; i < sharingList.size(); i++) {
        sharingRoleIDs[i] = ((UserRolePermission) sharingList.get(i))
            .getUserRoleID().toString();
      }

      maintCalendarRecordForm.setRoleIDsToShare(sharingRoleIDs);
    }

    return maintCalendarRecordForm;
  }

  private CalendarRecord selectInviteMeeting(HttpServletRequest request,
      SessionContainer sessionContainer, Connection connection,
      CalendarRecord calendarRecord) throws ApplicationException {
    AlertManager alertManager = new AlertManager(sessionContainer, connection);
    UpdateAlert updateAlert = null;
    List alertList = new ArrayList();
    alertList = alertManager.listUpdateAlertByObjectTypeObjectID(
        UpdateAlert.CALENDAR_TYPE, calendarRecord.getID());
    alertList.addAll(alertManager.listUpdateAlertByObjectTypeObjectID(
            UpdateAlert.CALENDAR_MODIFY_TYPE, calendarRecord.getID()));
    if (alertList != null) {
      if (alertList.size() > 0) {
        updateAlert = (UpdateAlert) alertList.get(0);

        //calendarRecord.setNotifyWay( /*updateAlert.getNotifyWay()*/null);
        calendarRecord.setUpdateAlertID(updateAlert.getID());

        List actionTypes = new ArrayList();
        UpdateAlertTypeDAObject updateAlertTypeDAO = new UpdateAlertTypeDAObject(
            sessionContainer, connection);
        actionTypes = updateAlertTypeDAO.getByUpdateAlertIDByOwnerID(
            updateAlert.getID(), UpdateAlert.INVITE_TYPE, updateAlert
                .getCreatorID());

        //actionTypes =
        // alertManager.listAlertUpdateTypeByUpdateAlertID(updateAlert.getID(),
        // UpdateAlert.INVITE_TYPE);
        if (actionTypes != null) {
          String[] actionString = new String[actionTypes.size()];

          for (int i = 0; i < actionTypes.size(); i++) {
            UpdateAlertType alertUpdateType = (UpdateAlertType) actionTypes
                .get(i); //getalertUpdateTypeList
            calendarRecord.setNeedReply(alertUpdateType.getNeedReply());
            calendarRecord.setNotifyWay(alertUpdateType.getNotifyWay());
            calendarRecord.setAlertSubject(alertUpdateType.getAlertSubject());
            UpdateAlertSystemLogDAObject updateSystemLogDAO = new UpdateAlertSystemLogDAObject(
                sessionContainer, connection);
            UpdateAlertSystemLog updateSystemLog = new UpdateAlertSystemLog();

            updateSystemLog.setUpdateAlertTypeID(alertUpdateType.getID());
            updateSystemLog.setActionUserID(sessionContainer.getUserRecordID());

            UpdateAlertSystemLog newUpdateSystemLog = (UpdateAlertSystemLog) updateSystemLogDAO
                .getByUpdateAlertTypeIDActionUserID(updateSystemLog
                    .getUpdateAlertTypeID(), updateSystemLog.getActionUserID());

            if (newUpdateSystemLog != null) {
              request.getSession().setAttribute("replyType",
                    newUpdateSystemLog.getActionReply());
            } else {
              request.getSession().setAttribute("replyType", "");
            }
          }
        }
      }
    }

    return calendarRecord;
  }

  private CalendarRecord setReplyAttributes(HttpServletRequest request,
      SessionContainer sessionContainer, Connection connection,
      CalendarRecord calendarRecord) throws ApplicationException {
    UpdateAlertSystemLogDAObject alertSystemLogDAO = new UpdateAlertSystemLogDAObject(
        sessionContainer, connection);

    List validUpdateAlertID = new ArrayList(1);
    validUpdateAlertID.add(calendarRecord.getUpdateAlertID());

    List systemLogList = alertSystemLogDAO.getSystemLogList(validUpdateAlertID);
    List replyOnAcceptAry=new ArrayList();
    List replyOnTentativeAry=new ArrayList();
    List replyOnRejectAry =new ArrayList();
    //UpdateAlertSystemLog tmpUpdateAlertSystemLog = new UpdateAlertSystemLog();
    //tmpUpdateAlertSystemLog.setActionUserID(sessionContainer.getUserRecordID());
    //replyOnAcceptAry.add(tmpUpdateAlertSystemLog);
    if (systemLogList != null) {
      for (int i = 0; i < systemLogList.size(); i++) {
        UpdateAlertSystemLog alertSystemLog = (UpdateAlertSystemLog) systemLogList
            .get(i);
        replyOnAcceptAry = alertSystemLogDAO
            .getReplyActionByUpdateAlertID(alertSystemLog,
                UpdateAlert.ACCEPT_ON_REPLY);
        replyOnTentativeAry = alertSystemLogDAO
            .getReplyActionByUpdateAlertID(alertSystemLog,
                UpdateAlert.TENTATIVE_ON_REPLY);
        replyOnRejectAry = alertSystemLogDAO
            .getReplyActionByUpdateAlertID(alertSystemLog,
                UpdateAlert.REJECT_ON_REPLY);
      }
    }
    request.getSession().setAttribute("replyOnAcceptAry",
        new ArrayList(replyOnAcceptAry));
    request.getSession().setAttribute("replyOnTentativeAry",
        new ArrayList(replyOnTentativeAry));
    request.getSession().setAttribute("replyOnRejectAry",
        new ArrayList(replyOnRejectAry));
    return calendarRecord;
  }

  private CalendarRecord selectRecurringRecord(
      SessionContainer sessionContainer, Connection connection,
      CalendarRecord calendarRecord) throws ApplicationException {
    CalendarRecurDAObject calendarRecurDAO = new CalendarRecurDAObject(
        sessionContainer, connection);
    CalendarRecur calendarRecur = (CalendarRecur) calendarRecurDAO
        .getObjectByCalendarID(calendarRecord.getID());

    if (calendarRecur != null) {
      calendarRecord.setRecurStartDate(calendarRecur.getStartDate());
      calendarRecord.setRecurEndDate(calendarRecur.getEndDate());
      calendarRecord.setRepeatTimes(calendarRecur.getRepeatTimes());
      calendarRecord.setRecurType(calendarRecur.getRecurType());
      calendarRecord.setRepeatOn(calendarRecur.getRepeatOn());
      calendarRecord.setRepeatType(calendarRecur.getRepeatType());
      calendarRecord.setRepeatTypeDay(calendarRecur.getRepeatTypeDay());
      calendarRecord.setOccurType(calendarRecur.getOccurType());
      calendarRecord.setOccurMonth(calendarRecur.getOccurMonth());
      calendarRecord.setOccurWeekDay(calendarRecur.getOccurWeekDay());
    }

    return calendarRecord;
  }

  private ArrayList getAllOverlapList(HttpServletRequest request,AbstractActionForm form,Integer ID,ArrayList re) throws ApplicationException{
	  Connection conn = this.getConnection(request);
	  MaintCalendarRecordForm tmpForm = (MaintCalendarRecordForm) form;
    SessionContainer sessionContainer = this.getSessionContainer(request);
    CalendarRecord calendarRecord = null;
		ArrayList calendarListSharedByOthersInDateRange = null;
		ArrayList calendarListSharedByOthersInDateRanges = null;

    CalendarRecordDAObject calendarRecordDAO = new CalendarRecordDAObject(
			sessionContainer, conn);
      
	  ArrayList sortedList = new ArrayList();
	  ArrayList tempEventList = new ArrayList();
	  ArrayList eventList = new ArrayList();
    ListCalendarRecordForm listCalendarRecordForm = new ListCalendarRecordForm();
    //ListCalendarRecordBean.instanceFlag = false;
    //ListCalendarRecordBean listCalendarRecordBean = ListCalendarRecordBean.getInstance();
    CalendarRetrievalManager calendarRetrievalManager = new CalendarRetrievalManager(sessionContainer,conn);
    Integer staffID = new Integer(-1);

    for (int x = 0;x<re.size();x++){
    	CalendarRecord tmpCal = (CalendarRecord)re.get(x);
      tempEventList = calendarRetrievalManager.getSortedList(listCalendarRecordForm,
          request, "LD", sessionContainer.getUserRecordID().intValue(),
          staffID, tmpCal.getDatetime(), tmpCal.getEndtime());
      if (!Utility.isEmpty(tempEventList)) {
        eventList = calendarRetrievalManager.getNewSortedList(tempEventList);
				for (int i = 0; i < eventList.size(); i++) {
					calendarRecord = (CalendarRecord) eventList.get(i);
						if (!((tmpCal.getDatetime().before(calendarRecord.getDatetime()) && tmpCal.getEndtime().before(calendarRecord.getDatetime())) ||(tmpCal.getDatetime().after(calendarRecord.getEndtime()) && tmpCal.getEndtime().after(calendarRecord.getEndtime())))){
							if (Utility.isEmpty(form.getID())){
								sortedList.add(calendarRecord);
							} else if (!form.getID().equals(calendarRecord.getID().toString())){
								sortedList.add(calendarRecord);
							}
						}
				}
			}
    }

		Set IDs = new HashSet();
    for (int i=0;i<sortedList.size();i++){
    	CalendarRecord calendarReocrd = (CalendarRecord)sortedList.get(i);
    	IDs.add(calendarReocrd.getID());
    }
  	Iterator iIDs = IDs.iterator();
  	CalendarRecordDAObject calendarRecordDAObject = new CalendarRecordDAObject(sessionContainer,conn);
  	ArrayList resultList = new ArrayList();
  	while(iIDs.hasNext()){
  		resultList.add(calendarRecordDAObject.getByID((Integer)iIDs.next()));
  	}
	  
	return resultList;
  }
  //Add End
  
  private ArrayList getOverlapList(HttpServletRequest request,
      AbstractActionForm form, Integer ID) throws ApplicationException {
    Connection conn = this.getConnection(request);

    SessionContainer sessionCtx = this.getSessionContainer(request);
    CalendarRecordDAObject calendarRecordDAO = new CalendarRecordDAObject(
        sessionCtx, conn);

    MaintCalendarRecordForm tmpForm = (MaintCalendarRecordForm) form;
    ArrayList resultList = new ArrayList();
    ArrayList list = (ArrayList) calendarRecordDAO
        .getOverlapListByDatePeriodAndEventTypeAndCalendarID(sessionCtx
            .getUserRecordID(), tmpForm.getDatetime(), tmpForm.getEndtime(),
            new String[] { CalendarRecord.EVENT_TYPE_CALENDAR_MEETING,
                CalendarRecord.EVENT_TYPE_CALENDAR_EVENT }, ID, null);

    conn = null;
    if (!Utility.isEmpty(list)) {
      for (int i = 0; i < list.size(); i++) {
        CalendarRecord calendar = (CalendarRecord) list.get(i);
        if (!Utility.isEmpty(calendar) && !Utility.isEmpty(ID)
            && calendar.getID().intValue() != ID.intValue()) {
          resultList.add(calendar);
        }
      }
    }

    return resultList;

  }

  private void setSystemLogToRead(Integer systemLogID,
      HttpServletRequest request) throws ApplicationException {
    Connection conn = this.getConnection(request);
    AlertManager alertManager = new AlertManager(this
        .getSessionContainer(request), conn);
    if (systemLogID != null) {
      if (alertManager.checkForSystemLogActionByActionType(systemLogID,
          UpdateAlertLogAction.READ_ACTION)) {
        //Got READ record; Can go delete the READ reocrd to mark as un-read
        //alertManager.deleteLogActionBySystemLogID(systemLogID);
        //alertManager.deleteLogActionBySystemLogIDCurActor(systemLogID);//Update By Jim.Zhou			2006/06/30		Bug #3950
      } else {
        //Go create read record
        UpdateAlertSystemLog systemLog = new UpdateAlertSystemLog();
        systemLog.setID(systemLogID);
        alertManager.createSystemLogAction(systemLog,
            UpdateAlertLogAction.READ_ACTION, null, null);
      }
    }
    try {
      conn.commit();
    } catch (Exception e) {

    }

  }

  protected void updateSubCalendar(ActionMapping mapping,
      AbstractActionForm form, HttpServletRequest request,
      HttpServletResponse response) throws ApplicationException {
    Connection connection = this.getConnection(request);
    SessionContainer sessionContainer = this.getSessionContainer(request);
    AlertManager alertManager = new AlertManager(sessionContainer, connection);
    UpdateAlert newUpdateAlert = null;
    CalendarRecord parentCalendarRecord = null;
    CalendarRecordDAObject calendarRecordDAObject = new CalendarRecordDAObject(
        sessionContainer, connection);
    AlertManager am = new AlertManager(sessionContainer, connection);
    int minuteInterval = SystemParameterFactory.getSystemParameterInteger(SystemParameterConstant.CALENDAR_DEFAULT_TIMEPICKER_INTERVAL).intValue();
    try {
      MaintCalendarRecordForm tmpForm = (MaintCalendarRecordForm) form;
      if (!Utility.isEmpty(tmpForm.getParentID())) {
        List subList = calendarRecordDAObject.getListByParentID(tmpForm
            .getParentID());
        for (int i = 0; i < subList.size(); i++) {
          CalendarRecord subCalendarRecord = (CalendarRecord) subList.get(i);
          if (CalendarRecord.EVENT_TYPE_CALENDAR_MEETING
              .equals(subCalendarRecord.getEventType())) {
            UpdateAlertDAObject updateAlertDAO = new UpdateAlertDAObject(
                sessionContainer, connection);
            UpdateAlertSystemLogDAObject updateAlertSystemLogDAO = new UpdateAlertSystemLogDAObject(
                sessionContainer, connection);
            UpdateAlertTypeDAObject updateAlertTypeDAO = new UpdateAlertTypeDAObject(
                sessionContainer, connection);

            UpdateAlert updateAlert = (UpdateAlert) updateAlertDAO
                .getByObjectTypeObjectID(UpdateAlert.CALENDAR_TYPE,
                    subCalendarRecord.getID());

            if (!Utility.isEmpty(updateAlert)) {
              List updateAlertTypeList = updateAlertTypeDAO
                  .getByUpdateAlertIDByOwnerID(updateAlert.getID(), "ALL",
                      sessionContainer.getUserRecordID());

              for (int j = 0; j < updateAlertTypeList.size(); j++) {
                UpdateAlertType updateAlertType = (UpdateAlertType) updateAlertTypeList
                    .get(j);

                //delete updateAlertSystemLog
                UpdateAlertSystemLog updateAlertSystemLog = (UpdateAlertSystemLog) updateAlertSystemLogDAO
                    .getByUpdateAlertTypeIDActionUserID(
                        updateAlertType.getID(), sessionContainer
                            .getUserRecordID());

                if (!Utility.isEmpty(updateAlertSystemLog)) {
                  updateAlertSystemLogDAO.deleteObject(updateAlertSystemLog);
                }

                //delete updateAlertType
                updateAlertTypeDAO.deleteObject(updateAlertType);
              }

              //delete updateAlert
              updateAlertDAO.deleteObject(updateAlert);
              if ((subCalendarRecord.getReminderType() != null)) {
                updateAlert.setObjectType(UpdateAlert.CALENDAR_TYPE);
                updateAlert.setObjectID(subCalendarRecord.getID());
                updateAlert.setCreatorName(subCalendarRecord.getCreatorName());

                List userRecordIDList = new ArrayList(1);
                userRecordIDList.add(sessionContainer.getUserRecordID());

                Date date = new Date(subCalendarRecord.getDatetime().getTime());

                try {
                  am.delScheduleJobNotification(updateAlert);
                } catch (Exception e) {
                }
              }
            }

            //Recurring
            if (subCalendarRecord.getIsRecurrence() != null) {
              CalendarRecurDAObject calendarRecurDAO = new CalendarRecurDAObject(
                  sessionContainer, connection);
              CalendarRecur calendarRecur = (CalendarRecur) calendarRecurDAO
                  .getObjectByCalendarID(subCalendarRecord.getID());
              calendarRecurDAO.deleteObjectByID(calendarRecur.getID());
            }

            //update alert
            if (CalendarRecord.EVENT_TYPE_CALENDAR_MEETING
                .equals(subCalendarRecord.getEventType())) {
              subCalendarRecord = updateUpdateAlert(request, sessionContainer,
                  connection, subCalendarRecord, am, "D", true);
            }
          }
          calendarRecordDAObject.deleteObjectByID(subCalendarRecord.getID());
        }
        //calendarRecordDAObject.deleteByParentID(new
        // Integer(tmpForm.getParentID()));
      }

      String subMeetingTitle;

      //define the form
      String subMeetingStartDate;

      //define the form
      String subMeetingEndtDate;

      //define the form
      String subMeetingStartHour;

      //define the form
      String subMeetingStartMinute;

      //define the form
      String subMeetingEndDate;
      String subMeetingEndHour;
      String subMeetingEndMinute;
      String subMeetingPriority;
      String subMeetingIsWholeDay;
      String subMeetingVenue;
      String subMeetingDetail;

      Integer parentID = new Integer(0);

      //CalendarRecord tempCalendarRecord = new CalendarRecord();
      //get the submeeting information to tempCalendarRecordForm
      MaintCalendarRecordForm tempCalendarRecordForm = (MaintCalendarRecordForm) form;

      for (int loopMeeting = 0; loopMeeting < tempCalendarRecordForm
          .getSubMeetingNum(); loopMeeting++) {
        subMeetingTitle = tempCalendarRecordForm.getTitle();
        subMeetingStartDate = request.getParameter("subMeetingStartDate" + "_"
            + loopMeeting);
        subMeetingEndtDate = request.getParameter("subMeetingEndtDate" + "_"
            + loopMeeting);
        subMeetingStartHour = request.getParameter("subMeetingStartHour" + "_"
            + loopMeeting);
        subMeetingStartMinute = request.getParameter("subMeetingStartMinute"
            + "_" + loopMeeting);
        subMeetingEndDate = request.getParameter("subMeetingEndDate" + "_"
            + loopMeeting);
        subMeetingEndHour = request.getParameter("subMeetingEndHour" + "_"
            + loopMeeting);
        subMeetingEndMinute = request.getParameter("subMeetingEndMinute" + "_"
            + loopMeeting);
        subMeetingPriority = request.getParameter("subMeetingPriority" + "_"
            + loopMeeting);
        subMeetingIsWholeDay = request.getParameter("subMeetingIsWholeDay"
            + "_" + loopMeeting);
        /*
         * if("Y".equals(subMeetingIsWholeDay)){ subMeetingStartHour="00";
         * subMeetingStartMinute="00"; subMeetingEndHour="23";
         * subMeetingEndMinute="59"; }
         */
        subMeetingVenue = request.getParameter("subMeetingVenue" + "_"
            + loopMeeting);
        subMeetingDetail = request.getParameter("subMeetingDetail" + "_"
            + loopMeeting);
        if ((subMeetingStartHour+subMeetingStartMinute).compareTo(subMeetingEndHour+subMeetingEndMinute)>0) {
        	throw new ApplicationException("calendar.error.startdate");
        }
        tempCalendarRecordForm.setTitle(subMeetingTitle);
        tempCalendarRecordForm.setStartDate(subMeetingStartDate);
        tempCalendarRecordForm.setEndDate(subMeetingEndtDate);
        tempCalendarRecordForm.setStartHour(subMeetingStartHour);
        tempCalendarRecordForm.setStartMinute(subMeetingStartMinute);
        tempCalendarRecordForm.setEndHour(subMeetingEndHour);
        tempCalendarRecordForm.setEndMinute(subMeetingEndMinute);
        tempCalendarRecordForm.setPriority(subMeetingPriority);
        tempCalendarRecordForm.setIsWholeDay(subMeetingIsWholeDay);
        tempCalendarRecordForm.setVenue(subMeetingVenue);
        tempCalendarRecordForm.setDetail(subMeetingDetail);

        tempCalendarRecordForm.setReminderType(((tempCalendarRecordForm
            .getEmailReminder() == null) ? "" : tempCalendarRecordForm
            .getEmailReminder())
            + ","
            + ((tempCalendarRecordForm.getSystemReminder() == null) ? ""
                : tempCalendarRecordForm.getSystemReminder()));

        if (!(CalendarRecord.NAV_MODE_LIST_TODO.equals(tempCalendarRecordForm
            .getEventType()))
            && (tempCalendarRecordForm.getEndtime() == null)) {
          tempCalendarRecordForm = this.setFormDate(tempCalendarRecordForm);

          //tempCalendarRecordForm.setEndDate(tempCalendarRecordForm.getStartDate());
        }

        //reset the starttime and endtime if it is a wholeday event
        if ("Y".equals(tempCalendarRecordForm.getIsWholeDay())) {
          tempCalendarRecordForm.setStartHour("00");
          tempCalendarRecordForm.setStartMinute("00");
          tempCalendarRecordForm.setEndHour("23");
          tempCalendarRecordForm.setEndMinute(String.valueOf(60-minuteInterval));
        }
        String overlap = "yes";
        if (!Utility.isEmpty(request.getParameter("Overlap"))) {
          overlap = request.getParameter("Overlap");
        }
        //check overlap with others
        if ("yes".equals(overlap)
            && !"true"
                .equals(SystemParameterFactory
                    .getSystemParameter(SystemParameterConstant.CALENDAR_ALLOW_OVERLAP))) {
          if (!CalendarRecord.EVENT_TYPE_CALENDAR_TODO
              .equals(tempCalendarRecordForm.getEventType())
              && (tempCalendarRecordForm.getEventType() != null)) {
            ArrayList overlapList = getOverlapList(request, form, null);
            //if (overlapWithOthers(request, form, null)) {
            if (overlapList.size() > 0) {
              request.setAttribute("overlapList", overlapList);
              throw new ApplicationException(
                  ErrorConstant.CALENDAR_OVERLAP_ERROR);
            }
          }
        }
      }

      //"Recurring Start date" should not be allowed to set prior to the "Due
      // Date"
      //  Timestamp strCurrentDate = new Timestamp(new
      // Date(TextUtility.formatTimestamp(Utility.getCurrentTimestamp()))) ;
      Timestamp strCurrentDate = Utility.getCurrentTimestamp();

      //because the strCurrentDate have hh - mm -ss, so getRecurStartDate add 1
      /*if (!Utility.isEmpty(tmpForm.getIsRecurrence())
          && strCurrentDate.after(Utility.addDay(tmpForm
              .formateStringToTimestamp(tmpForm.getRecurStartDate()), 1))) {
        throw new ApplicationException(
            ErrorConstant.CALENDAR_RECURRING_START_DATE_PRIORDUEDATE_ERROR);
      }*/

      //"Recurring End date" should not be allowed to set prior to the
      // "Recurring Start Date"
      if (!Utility.isEmpty(tmpForm.getIsRecurrence())
          && tmpForm.getRecurEndDate() != null) {
        if (tmpForm.formateStringToTimestamp(tmpForm.getRecurStartDate())
            .after(tmpForm.formateStringToTimestamp(tmpForm.getRecurEndDate()))) {
          throw new ApplicationException(
              ErrorConstant.CALENDAR_RECURRING_RANGE_ERROR);
        }
      }

      for (int loopMeeting = 0; loopMeeting < tempCalendarRecordForm
          .getSubMeetingNum(); loopMeeting++) {
        subMeetingTitle = request.getParameter("subMeetingTitle" + "_"
            + loopMeeting);
        subMeetingStartDate = request.getParameter("subMeetingStartDate" + "_"
            + loopMeeting);
        subMeetingEndtDate = request.getParameter("subMeetingEndtDate" + "_"
            + loopMeeting);
        subMeetingStartHour = request.getParameter("subMeetingStartHour" + "_"
            + loopMeeting);
        subMeetingStartMinute = request.getParameter("subMeetingStartMinute"
            + "_" + loopMeeting);
        subMeetingEndDate = request.getParameter("subMeetingEndDate" + "_"
            + loopMeeting);
        subMeetingEndHour = request.getParameter("subMeetingEndHour" + "_"
            + loopMeeting);
        subMeetingEndMinute = request.getParameter("subMeetingEndMinute" + "_"
            + loopMeeting);
        subMeetingPriority = request.getParameter("subMeetingPriority" + "_"
            + loopMeeting);
        subMeetingIsWholeDay = request.getParameter("subMeetingIsWholeDay"
            + "_" + loopMeeting);
        subMeetingVenue = request.getParameter("subMeetingVenue" + "_"
            + loopMeeting);
        subMeetingDetail = request.getParameter("subMeetingDetail" + "_"
            + loopMeeting);

        tempCalendarRecordForm.setTitle(subMeetingTitle);
        tempCalendarRecordForm.setStartDate(subMeetingStartDate);
        tempCalendarRecordForm.setEndDate(subMeetingEndtDate);
        tempCalendarRecordForm.setStartHour(subMeetingStartHour);
        tempCalendarRecordForm.setStartMinute(subMeetingStartMinute);
        tempCalendarRecordForm.setEndHour(subMeetingEndHour);
        tempCalendarRecordForm.setEndMinute(subMeetingEndMinute);
        tempCalendarRecordForm.setPriority(subMeetingPriority);
        tempCalendarRecordForm.setIsWholeDay(subMeetingIsWholeDay);
        tempCalendarRecordForm.setVenue(subMeetingVenue);
        tempCalendarRecordForm.setDetail(subMeetingDetail);

        tempCalendarRecordForm.setReminderType(((tempCalendarRecordForm
            .getEmailReminder() == null) ? "" : tempCalendarRecordForm
            .getEmailReminder())
            + ","
            + ((tempCalendarRecordForm.getSystemReminder() == null) ? ""
                : tempCalendarRecordForm.getSystemReminder()));

        if (!(CalendarRecord.NAV_MODE_LIST_TODO.equals(tempCalendarRecordForm
            .getEventType()))
            && (tempCalendarRecordForm.getEndtime() == null)) {
          tempCalendarRecordForm = this.setFormDate(tempCalendarRecordForm);

          //tempCalendarRecordForm.setEndDate(tempCalendarRecordForm.getStartDate());
        }

        //reset the starttime and endtime if it is a wholeday event
        if ("Y".equals(tempCalendarRecordForm.getIsWholeDay())) {
          tempCalendarRecordForm.setStartHour("00");
          tempCalendarRecordForm.setStartMinute("00");
          tempCalendarRecordForm.setEndHour("23");
          tempCalendarRecordForm.setEndMinute(String.valueOf(60-minuteInterval));
        }

        //check overlap with others
        /*
         * if (!"true".equals( SystemParameterFactory.getSystemParameter(
         * SystemParameterConstant.CALENDAR_ALLOW_OVERLAP))) { if
         * (!CalendarRecord.EVENT_TYPE_CALENDAR_TODO.equals(
         * tempCalendarRecordForm.getEventType()) &&
         * (tempCalendarRecordForm.getEventType() != null)) { if
         * (overlapWithOthers(request, form, null)) { throw new
         * ApplicationException(ErrorConstant.CALENDAR_OVERLAP_ERROR); } } }
         */
        CalendarRecord calendarRecord1 = (CalendarRecord) tempCalendarRecordForm
            .getFormData();

        calendarRecord1.setParentID(parentID);
        CalendarRecord calendarRecord = (CalendarRecord) calendarRecordDAObject
            .insertObject(calendarRecord1);

        //      if(loopMeeting == 0)
        if (parentID.intValue() == 0) {
          parentID = calendarRecord.getID();
        }

        //SHARING BY USERS, ROLES, AND GROUPS
        if (!(CalendarRecord.SHARE_TYPE_PRIVATE.equals((calendarRecord
            .getShareType())))) {
          tempCalendarRecordForm = this.createCalendarRecordSharing(
              sessionContainer, connection, tempCalendarRecordForm);
        }

        //Creat new alert information
        if (CalendarRecord.EVENT_TYPE_CALENDAR_MEETING.equals(calendarRecord
            .getEventType())) {
          String recipientType = (request.getParameter("recipientType") == null) ? ""
              : request.getParameter("recipientType");
          String[] notifyWayString = (request.getParameterValues("notifyWay") == null) ? new String[0]
              : request.getParameterValues("notifyWay");

          if (notifyWayString.length > 0) {
            StringBuffer str = new StringBuffer();

            for (int i = 0; i < notifyWayString.length; i++) {
              str.append(notifyWayString[i]).append(",");
            }

            calendarRecord.setNotifyWay(str.toString());
          }

          newUpdateAlert = this.createUpdateAlert(request,
              calendarRecord, alertManager);

          if (newUpdateAlert != null) {
            calendarRecord.setUpdateAlertID(newUpdateAlert.getID());
          }
        }

        //REMINDER HANDLING
        if ((tempCalendarRecordForm.getEmailReminder() != null)
            || (tempCalendarRecordForm.getSystemReminder() != null)) {
          //Use public AlertManager to control
          UpdateAlert updateAlert = new UpdateAlert();
          updateAlert.setObjectType(UpdateAlert.CALENDAR_TYPE);
          updateAlert.setObjectID(calendarRecord.getID());
          alertManager.newReminderAlert(updateAlert, UpdateAlert.CALENDAR_TYPE,
              calendarRecord.getID(), calendarRecord);
        }

        //recurring record
        if (calendarRecord.getIsRecurrence() != null) {
          this.createRecurringRecord(calendarRecord, sessionContainer,
              connection);
        }

        tempCalendarRecordForm.setFormData(calendarRecord);
        tempCalendarRecordForm.setDatetime(calendarRecord.getDatetime());
        tempCalendarRecordForm.setEndtime(calendarRecord.getEndtime());
      }

      //UPDATE PARENT OBJECT
      if (parentID.intValue() != 0) {
        parentCalendarRecord = (CalendarRecord) calendarRecordDAObject
            .getObjectByID(parentID);
        parentCalendarRecord.setParentID(parentID);
        calendarRecordDAObject.updateObject(parentCalendarRecord);
      }
    } catch (ApplicationException aape) {
      throw aape;
    } catch (Exception e) {
      log.error("Retrieve calendar record information.", e);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR, e);
    }
  }
  
  protected void expCalendar(HttpServletRequest request, HttpServletResponse response, AbstractActionForm maintForm){
    try{
      MaintCalendarRecordForm tmpForm = (MaintCalendarRecordForm) maintForm;      
      SessionContainer sessionContainer = this.getSessionContainer(request);
      Connection conn = this.getConnection(request);
      CalendarRecordDAObject calendarRecordDAO = new CalendarRecordDAObject(
          sessionContainer, conn);
      CalendarRecord calendarRecord = (CalendarRecord) calendarRecordDAO
          .getObjectByID(TextUtility.parseIntegerObj(tmpForm.getID()));
      Calendar calendar = new Calendar();
      calendar = calendarRecord.expToIcalendar();
      String title = calendarRecord.getTitle();
      response.addHeader("Content-Transfer-Encoding", "base64");
      String filename = title+".ics";
      response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename,"UTF-8" ) + "\"");
      ServletOutputStream sos =response.getOutputStream();
      CalendarOutputter outputter = new CalendarOutputter();
      outputter.output(calendar, sos);
      sos.close();
    } catch(Exception aape){
      log.error(aape);
    }
    
  }


  private boolean checkLoginId(ActionMapping mapping, ActionForm form,
	      HttpServletRequest request, HttpServletResponse response)
  throws ApplicationException {
	    Connection connection = this.getConnection(request);
	    SessionContainer sessionContainer = this.getSessionContainer(request);
	  MaintCalendarRecordForm maintCalendarRecordForm = (MaintCalendarRecordForm)form;
	  //ListCalendarRecordBean.instanceFlag = false;
	  //ListCalendarRecordBean intance=ListCalendarRecordBean.getInstance();
	  CalendarRetrievalManager calendarRetrievalManager = new CalendarRetrievalManager(sessionContainer,connection);
	  String[] sUser = maintCalendarRecordForm.getUserList();
	  String[] sRole = maintCalendarRecordForm.getRoleList();
	  String[] sGroup = maintCalendarRecordForm.getGroupList();
	  boolean nullFlag = true;
	  for (int i=0;i<sUser.length;i++){
		  if (!Utility.isEmpty(sUser[i])){
			  nullFlag = false;
			  break;
		  }
	  }
	  if (nullFlag){
		  sUser = null;
	  }
	  nullFlag = true;
	  for (int i=0;i<sRole.length;i++){
		  if (!Utility.isEmpty(sRole[i])){
			  nullFlag = false;
			  break;
		  }
	  }
	  if (nullFlag){
		  sRole = null;
	  }
	  nullFlag = true;
	  for (int i=0;i<sGroup.length;i++){
		  if (!Utility.isEmpty(sGroup[i])){
			  nullFlag = false;
			  break;
		  }
	  }
	  if (nullFlag){
		  sGroup = null;
	  }
	  
	  ArrayList IDs = (ArrayList)calendarRetrievalManager.getSelectUserIDList(sessionContainer,
			  connection,
			  sUser,
			  sRole,
			  sGroup);
	  if (IDs.indexOf(sessionContainer.getUserRecordID())!=-1){
		  return true;
	  }
	  return false;
  }

  public List selfTimeConflict(SessionContainer sessionContainer,Connection conn,AbstractActionForm form)throws ApplicationException {
  	CalendarRetrievalManager calendarRetrievalManager = new CalendarRetrievalManager(sessionContainer,conn);
  	ArrayList result = (ArrayList)calendarRetrievalManager.createVirtualRecordForRecurringForForm(sessionContainer,conn,form,((MaintCalendarRecordForm)form).getDatetime(),((MaintCalendarRecordForm)form).getEndtime(),"M","R");
  	if (!Utility.isEmpty(result)){
    	for (int i=0;i<result.size();i++){
    		CalendarRecord tmpCal = (CalendarRecord)result.get(i);
    		for (int j=i+1;j<result.size();j++){
      		CalendarRecord tmpCal2 = (CalendarRecord)result.get(j);
    			if (!((tmpCal.getDatetime().before(tmpCal2.getDatetime()) && tmpCal.getEndtime().before(tmpCal2.getDatetime()))
    						|| tmpCal.getDatetime().after(tmpCal2.getEndtime()) && tmpCal.getEndtime().after(tmpCal2.getEndtime()))){
    				if (i==0 && j==1 && tmpCal.getDatetime().equals(tmpCal2.getDatetime()) && tmpCal.getEndtime().equals(tmpCal2.getEndtime())){
    					continue;
    				}
    				throw new ApplicationException(ErrorConstant.CALENDAR_RECURRING_CONFLICT_SELF);
    			}
    		}
    	}
  	}
  	return result;
  }
}